0
# Schema Introspection
1
2
Methods for examining schema structure, accessing field definitions, and navigating schema hierarchies.
3
4
## Capabilities
5
6
### Schema Definition Access
7
8
Methods to access and examine schema definitions.
9
10
```typescript { .api }
11
/**
12
* Gets the complete resolved schema definition
13
* @returns Complete schema definition with all fields resolved
14
*/
15
schema(): ResolvedSchemaDefinition;
16
17
/**
18
* Gets the definition for a specific field key
19
* @param key - Field key to get definition for
20
* @returns Field definition or null if key doesn't exist
21
*/
22
schema(key: string): StandardSchemaKeyDefinition | null;
23
24
/**
25
* Gets all possible definitions for a field key (for union types)
26
* @param key - Field key to get definitions for
27
* @returns Array of field definitions
28
*/
29
schemas(key: string): StandardSchemaKeyDefinition[];
30
31
/**
32
* Gets flattened schema with all subschemas merged
33
* @returns Merged schema definition
34
*/
35
mergedSchema(): SchemaDefinition;
36
```
37
38
**Usage Examples:**
39
40
```typescript
41
import SimpleSchema from "simpl-schema";
42
43
const userSchema = new SimpleSchema({
44
name: String,
45
email: {
46
type: String,
47
regEx: SimpleSchema.RegEx.Email,
48
label: "Email Address"
49
},
50
role: SimpleSchema.oneOf(
51
{ type: String, allowedValues: ['admin', 'user'] },
52
{ type: Number, allowedValues: [1, 2] }
53
)
54
});
55
56
// Get complete schema
57
const fullSchema = userSchema.schema();
58
console.log(Object.keys(fullSchema)); // ['name', 'email', 'role']
59
60
// Get specific field definition
61
const emailDef = userSchema.schema('email');
62
console.log(emailDef?.type); // StringConstructor
63
console.log(emailDef?.label); // "Email Address"
64
65
// Get definitions for union type field
66
const roleDefs = userSchema.schemas('role');
67
console.log(roleDefs.length); // 2 - one for string, one for number
68
69
// Get merged schema (flattened)
70
const merged = userSchema.mergedSchema();
71
console.log(merged);
72
```
73
74
### Field Definition Evaluation
75
76
Get evaluated field definitions with function-based properties resolved.
77
78
```typescript { .api }
79
/**
80
* Gets evaluated definition for a field key with functions resolved
81
* @param key - Field key to get definition for
82
* @param propList - List of specific properties to evaluate
83
* @param functionContext - Context object passed to property functions
84
* @returns Evaluated field definition
85
*/
86
getDefinition(
87
key: string,
88
propList?: string[],
89
functionContext?: Record<string, unknown>
90
): StandardSchemaKeyDefinitionWithSimpleTypes;
91
92
/**
93
* Gets all evaluated definitions for a field key (for union types)
94
* @param key - Field key to get definitions for
95
* @param propList - List of specific properties to evaluate
96
* @param functionContext - Context object passed to property functions
97
* @returns Array of evaluated field definitions
98
*/
99
getDefinitions(
100
key: string,
101
propList?: string[],
102
functionContext?: Record<string, unknown>
103
): StandardSchemaKeyDefinitionWithSimpleTypes[];
104
```
105
106
**Usage Examples:**
107
108
```typescript
109
const dynamicSchema = new SimpleSchema({
110
name: String,
111
description: {
112
type: String,
113
max: function() {
114
return this.key === 'shortDescription' ? 100 : 1000;
115
},
116
optional: function() {
117
return this.field('type').value === 'basic';
118
}
119
}
120
});
121
122
// Get evaluated definition with context
123
const context = {
124
key: 'description',
125
field: (key) => ({ value: 'premium' })
126
};
127
128
const definition = dynamicSchema.getDefinition('description', undefined, context);
129
console.log(definition.max); // 1000 (function resolved)
130
console.log(definition.optional); // false (function resolved)
131
132
// Get specific properties only
133
const limited = dynamicSchema.getDefinition('description', ['max'], context);
134
console.log('max' in limited); // true
135
console.log('optional' in limited); // false - not requested
136
```
137
138
### Schema Structure Navigation
139
140
Methods for navigating and understanding schema structure.
141
142
```typescript { .api }
143
/**
144
* Finds the schema instance that defines a specific key
145
* @param key - Field key to search for
146
* @returns Tuple of [schema instance, local key] or [null, null] if not found
147
*/
148
nearestSimpleSchemaInstance(key: string): [SimpleSchema | null, string | null];
149
150
/**
151
* Iterates through ancestor schemas that contain a key
152
* @param key - Field key to search ancestors for
153
* @param func - Function to call for each ancestor schema
154
*/
155
forEachAncestorSimpleSchema(
156
key: string,
157
func: (
158
ssInstance: SimpleSchema,
159
ancestor: string,
160
ancestorGenericKey: string
161
) => void
162
): void;
163
164
/**
165
* Gets a scoped schema for an object field
166
* @param key - Object field key to get schema for
167
* @returns SimpleSchema instance scoped to the object field
168
*/
169
getObjectSchema(key: string): SimpleSchema;
170
171
/**
172
* Gets child keys for object fields
173
* @param keyPrefix - Optional prefix to filter keys
174
* @returns Array of child key names
175
*/
176
objectKeys(keyPrefix?: string): string[];
177
178
/**
179
* Checks if a key is allowed by the schema
180
* @param key - Key to check
181
* @returns true if key is defined in schema
182
*/
183
allowsKey(key: string): boolean;
184
185
/**
186
* Checks if a key is inside a blackbox object
187
* @param key - Key to check
188
* @returns true if key is within a blackbox field
189
*/
190
keyIsInBlackBox(key: string): boolean;
191
192
/**
193
* Gets the raw schema definition passed to constructor
194
* Only available if keepRawDefinition option was set to true
195
* @returns Raw schema definition object or null
196
*/
197
get rawDefinition(): SchemaDefinitionWithShorthand | null;
198
```
199
200
**Usage Examples:**
201
202
```typescript
203
const addressSchema = new SimpleSchema({
204
street: String,
205
city: String,
206
state: String
207
});
208
209
const userSchema = new SimpleSchema({
210
name: String,
211
address: addressSchema,
212
preferences: {
213
type: Object,
214
blackbox: true
215
}
216
});
217
218
// Find which schema defines a key
219
const [schema, localKey] = userSchema.nearestSimpleSchemaInstance('address.street');
220
console.log(schema === addressSchema); // true
221
console.log(localKey); // 'street'
222
223
// Get object schema
224
const addrSchema = userSchema.getObjectSchema('address');
225
console.log(addrSchema === addressSchema); // true
226
227
// Get object keys
228
const addressKeys = userSchema.objectKeys('address');
229
console.log(addressKeys); // ['address.street', 'address.city', 'address.state']
230
231
const topLevelKeys = userSchema.objectKeys();
232
console.log(topLevelKeys); // ['name', 'address', 'preferences']
233
234
// Check if keys are allowed
235
console.log(userSchema.allowsKey('name')); // true
236
console.log(userSchema.allowsKey('address.street')); // true
237
console.log(userSchema.allowsKey('nonexistent')); // false
238
239
// Check blackbox status
240
console.log(userSchema.keyIsInBlackBox('preferences.theme')); // true
241
console.log(userSchema.keyIsInBlackBox('address.street')); // false
242
243
// Access raw definition (if keepRawDefinition: true was used)
244
const schemaWithRaw = new SimpleSchema({
245
name: String,
246
age: Number
247
}, { keepRawDefinition: true });
248
249
console.log(schemaWithRaw.rawDefinition);
250
// { name: String, age: Number } - exact object passed to constructor
251
252
const schemaWithoutRaw = new SimpleSchema({
253
name: String,
254
age: Number
255
});
256
console.log(schemaWithoutRaw.rawDefinition); // null
257
```
258
259
### Field Property Access
260
261
Methods to access specific field properties and metadata.
262
263
```typescript { .api }
264
/**
265
* Gets simplified type string for a field
266
* @param key - Field key to get type for
267
* @returns Type string (e.g., 'String', 'Number', 'Array')
268
*/
269
getQuickTypeForKey(key: string): string;
270
271
/**
272
* Gets allowed values array for a field
273
* @param key - Field key to get allowed values for
274
* @returns Array of allowed values or null if no restriction
275
*/
276
getAllowedValuesForKey(key: string): any[] | null;
277
278
/**
279
* Gets default value for a field
280
* @param key - Field key to get default value for
281
* @returns Default value or undefined if none set
282
*/
283
defaultValue(key: string): unknown;
284
285
/**
286
* Gets property value for a field with function resolution
287
* @param key - Field key
288
* @param prop - Property name to get
289
* @param functionContext - Context for function-based properties
290
* @returns Property value
291
*/
292
get(key: string, prop: string, functionContext?: Record<string, unknown>): any;
293
```
294
295
**Usage Examples:**
296
297
```typescript
298
const productSchema = new SimpleSchema({
299
name: String,
300
category: {
301
type: String,
302
allowedValues: ['electronics', 'books', 'clothing']
303
},
304
price: {
305
type: Number,
306
min: 0
307
},
308
tags: [String],
309
status: {
310
type: String,
311
defaultValue: 'active'
312
},
313
priority: {
314
type: Number,
315
max: function() {
316
return this.field('category').value === 'electronics' ? 10 : 5;
317
}
318
}
319
});
320
321
// Get quick type strings
322
console.log(productSchema.getQuickTypeForKey('name')); // 'String'
323
console.log(productSchema.getQuickTypeForKey('price')); // 'Number'
324
console.log(productSchema.getQuickTypeForKey('tags')); // 'Array'
325
326
// Get allowed values
327
const categories = productSchema.getAllowedValuesForKey('category');
328
console.log(categories); // ['electronics', 'books', 'clothing']
329
330
const nameAllowed = productSchema.getAllowedValuesForKey('name');
331
console.log(nameAllowed); // null - no restriction
332
333
// Get default values
334
console.log(productSchema.defaultValue('status')); // 'active'
335
console.log(productSchema.defaultValue('name')); // undefined
336
337
// Get property with context
338
const context = { field: (key) => ({ value: 'electronics' }) };
339
const maxPriority = productSchema.get('priority', 'max', context);
340
console.log(maxPriority); // 10 (function resolved with context)
341
```
342
343
### Labels and Messages
344
345
Methods for accessing field labels and generating error messages.
346
347
```typescript { .api }
348
/**
349
* Sets labels for multiple fields
350
* @param labels - Object mapping field keys to label strings or functions
351
*/
352
labels(labels: Record<string, string | Function>): void;
353
354
/**
355
* Gets all field labels
356
* @returns Object mapping field keys to label strings
357
*/
358
label(): Record<string, string>;
359
360
/**
361
* Gets label for a specific field
362
* @param key - Field key to get label for
363
* @returns Label string or null if no label set
364
*/
365
label(key: string): string | null;
366
367
/**
368
* Gets formatted error message for a validation error
369
* @param errorInfo - ValidationError object to format
370
* @returns Formatted error message string
371
*/
372
messageForError(errorInfo: ValidationError): string;
373
```
374
375
**Usage Examples:**
376
377
```typescript
378
const userSchema = new SimpleSchema({
379
firstName: String,
380
lastName: String,
381
email: {
382
type: String,
383
label: "Email Address"
384
},
385
age: {
386
type: Number,
387
label: function() {
388
return "Age (years)";
389
}
390
}
391
});
392
393
// Set multiple labels
394
userSchema.labels({
395
firstName: "First Name",
396
lastName: "Last Name"
397
});
398
399
// Get all labels
400
const allLabels = userSchema.label();
401
console.log(allLabels);
402
// {
403
// firstName: "First Name",
404
// lastName: "Last Name",
405
// email: "Email Address",
406
// age: "Age (years)"
407
// }
408
409
// Get specific label
410
console.log(userSchema.label('email')); // "Email Address"
411
console.log(userSchema.label('nonexistent')); // null
412
413
// Format error message
414
const error = {
415
name: 'email',
416
type: 'regEx',
417
value: 'invalid-email'
418
};
419
420
const message = userSchema.messageForError(error);
421
console.log(message); // "Email Address must be a valid email address"
422
```
423
424
### Auto Value Functions
425
426
Methods for examining auto value function definitions.
427
428
```typescript { .api }
429
/**
430
* Gets details about all autoValue functions in the schema
431
* @returns Array of autoValue function details
432
*/
433
autoValueFunctions(): AutoValueFunctionDetails[];
434
435
/**
436
* Gets all blackbox field keys
437
* @returns Array of field keys that are marked as blackbox
438
*/
439
blackboxKeys(): string[];
440
441
interface AutoValueFunctionDetails {
442
key: string;
443
autoValue: AutoValueFunction;
444
fieldName: string;
445
}
446
```
447
448
**Usage Examples:**
449
450
```typescript
451
const postSchema = new SimpleSchema({
452
title: String,
453
slug: {
454
type: String,
455
autoValue() {
456
if (this.isInsert && !this.isSet) {
457
const title = this.field('title').value;
458
return title.toLowerCase().replace(/\s+/g, '-');
459
}
460
}
461
},
462
createdAt: {
463
type: Date,
464
autoValue() {
465
if (this.isInsert) {
466
return new Date();
467
}
468
}
469
},
470
updatedAt: {
471
type: Date,
472
autoValue() {
473
return new Date();
474
}
475
},
476
metadata: {
477
type: Object,
478
blackbox: true
479
}
480
});
481
482
// Get auto value function details
483
const autoValues = postSchema.autoValueFunctions();
484
console.log(autoValues.length); // 3
485
console.log(autoValues.map(av => av.key)); // ['slug', 'createdAt', 'updatedAt']
486
487
// Get blackbox keys
488
const blackboxKeys = postSchema.blackboxKeys();
489
console.log(blackboxKeys); // ['metadata']
490
```
491
492
## Types
493
494
```typescript { .api }
495
interface ResolvedSchemaDefinition {
496
[key: string]: StandardSchemaKeyDefinition;
497
}
498
499
interface StandardSchemaKeyDefinition {
500
type: SimpleSchemaGroup;
501
optional?: boolean;
502
// ... other field properties
503
}
504
505
interface StandardSchemaKeyDefinitionWithSimpleTypes {
506
type: SupportedTypes;
507
optional?: boolean;
508
// ... other field properties with functions resolved
509
}
510
511
type SchemaDefinition = Record<string, SchemaKeyDefinitionWithShorthand>;
512
513
interface AutoValueFunctionDetails {
514
key: string;
515
autoValue: AutoValueFunction;
516
fieldName: string;
517
}
518
519
interface ValidationError {
520
name: string;
521
type: string;
522
value: any;
523
message?: string;
524
[prop: string]: any;
525
}
526
```