@sinclair/typebox 0.26.0-dev.4 → 0.26.0-dev.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,9 +3,10 @@ import { ValueErrorIterator } from '../errors/index';
3
3
  export type CheckFunction = (value: unknown) => boolean;
4
4
  export declare class TypeCheck<T extends Types.TSchema> {
5
5
  private readonly schema;
6
+ private readonly references;
6
7
  private readonly checkFunc;
7
8
  private readonly code;
8
- constructor(schema: T, checkFunc: CheckFunction, code: string);
9
+ constructor(schema: T, references: Types.TSchema[], checkFunc: CheckFunction, code: string);
9
10
  /** Returns the generated assertion code used to validate this type. */
10
11
  Code(): string;
11
12
  /** Returns an iterator for each error in this value. */
@@ -20,14 +21,18 @@ export declare class TypeCompilerUnknownTypeError extends Error {
20
21
  readonly schema: Types.TSchema;
21
22
  constructor(schema: Types.TSchema);
22
23
  }
23
- export declare class TypeCompilerPreflightCheckError extends Error {
24
+ export declare class TypeCompilerDereferenceError extends Error {
25
+ readonly schema: Types.TRef;
26
+ constructor(schema: Types.TRef);
27
+ }
28
+ export declare class TypeCompilerTypeGuardError extends Error {
24
29
  readonly schema: Types.TSchema;
25
30
  constructor(schema: Types.TSchema);
26
31
  }
27
32
  /** Compiles Types for Runtime Type Checking */
28
33
  export declare namespace TypeCompiler {
29
34
  /** Returns the generated assertion code used to validate this type. */
30
- function Code<T extends Types.TSchema>(schema: T): string;
35
+ function Code<T extends Types.TSchema>(schema: T, references: Types.TSchema[]): string;
31
36
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
32
- function Compile<T extends Types.TSchema>(schema: T): TypeCheck<T>;
37
+ function Compile<T extends Types.TSchema>(schema: T, references?: Types.TSchema[]): TypeCheck<T>;
33
38
  }
@@ -27,7 +27,7 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.TypeCompiler = exports.TypeCompilerPreflightCheckError = exports.TypeCompilerUnknownTypeError = exports.MemberExpression = exports.TypeCheck = void 0;
30
+ exports.TypeCompiler = exports.TypeCompilerTypeGuardError = exports.TypeCompilerDereferenceError = exports.TypeCompilerUnknownTypeError = exports.MemberExpression = exports.TypeCheck = void 0;
31
31
  const Types = require("../typebox");
32
32
  const index_1 = require("../errors/index");
33
33
  const index_2 = require("../system/index");
@@ -36,8 +36,9 @@ const hash_1 = require("../value/hash");
36
36
  // TypeCheck
37
37
  // -------------------------------------------------------------------
38
38
  class TypeCheck {
39
- constructor(schema, checkFunc, code) {
39
+ constructor(schema, references, checkFunc, code) {
40
40
  this.schema = schema;
41
+ this.references = references;
41
42
  this.checkFunc = checkFunc;
42
43
  this.code = code;
43
44
  }
@@ -47,7 +48,7 @@ class TypeCheck {
47
48
  }
48
49
  /** Returns an iterator for each error in this value. */
49
50
  Errors(value) {
50
- return index_1.ValueErrors.Errors(this.schema, value);
51
+ return index_1.ValueErrors.Errors(this.schema, this.references, value);
51
52
  }
52
53
  /** Returns true if the value matches the compiled type. */
53
54
  Check(value) {
@@ -134,13 +135,20 @@ class TypeCompilerUnknownTypeError extends Error {
134
135
  }
135
136
  }
136
137
  exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError;
137
- class TypeCompilerPreflightCheckError extends Error {
138
+ class TypeCompilerDereferenceError extends Error {
138
139
  constructor(schema) {
139
- super('TypeCompiler: Preflight validation check failed for given schema');
140
+ super(`TypeCompiler: Unable to dereference schema with $id '${schema.$ref}'`);
140
141
  this.schema = schema;
141
142
  }
142
143
  }
143
- exports.TypeCompilerPreflightCheckError = TypeCompilerPreflightCheckError;
144
+ exports.TypeCompilerDereferenceError = TypeCompilerDereferenceError;
145
+ class TypeCompilerTypeGuardError extends Error {
146
+ constructor(schema) {
147
+ super('TypeCompiler: Preflight validation check failed to guard for the given schema');
148
+ this.schema = schema;
149
+ }
150
+ }
151
+ exports.TypeCompilerTypeGuardError = TypeCompilerTypeGuardError;
144
152
  /** Compiles Types for Runtime Type Checking */
145
153
  var TypeCompiler;
146
154
  (function (TypeCompiler) {
@@ -153,14 +161,17 @@ var TypeCompiler;
153
161
  function IsNumber(value) {
154
162
  return typeof value === 'number' && globalThis.Number.isFinite(value);
155
163
  }
164
+ function IsString(value) {
165
+ return typeof value === 'string';
166
+ }
156
167
  // -------------------------------------------------------------------
157
168
  // Types
158
169
  // -------------------------------------------------------------------
159
- function* Any(schema, value) {
170
+ function* Any(schema, references, value) {
160
171
  yield 'true';
161
172
  }
162
- function* Array(schema, value) {
163
- const expression = CreateExpression(schema.items, 'value');
173
+ function* Array(schema, references, value) {
174
+ const expression = CreateExpression(schema.items, references, 'value');
164
175
  yield `Array.isArray(${value}) && ${value}.every(value => ${expression})`;
165
176
  if (IsNumber(schema.minItems))
166
177
  yield `${value}.length >= ${schema.minItems}`;
@@ -169,7 +180,7 @@ var TypeCompiler;
169
180
  if (schema.uniqueItems === true)
170
181
  yield `((function() { const set = new Set(); for(const element of ${value}) { const hashed = hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true })())`;
171
182
  }
172
- function* BigInt(schema, value) {
183
+ function* BigInt(schema, references, value) {
173
184
  yield `(typeof ${value} === 'bigint')`;
174
185
  if (IsBigInt(schema.multipleOf))
175
186
  yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
@@ -182,13 +193,13 @@ var TypeCompiler;
182
193
  if (IsBigInt(schema.maximum))
183
194
  yield `${value} <= BigInt(${schema.maximum})`;
184
195
  }
185
- function* Boolean(schema, value) {
196
+ function* Boolean(schema, references, value) {
186
197
  yield `typeof ${value} === 'boolean'`;
187
198
  }
188
- function* Constructor(schema, value) {
189
- yield* Visit(schema.returns, `${value}.prototype`);
199
+ function* Constructor(schema, references, value) {
200
+ yield* Visit(schema.returns, references, `${value}.prototype`);
190
201
  }
191
- function* Date(schema, value) {
202
+ function* Date(schema, references, value) {
192
203
  yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`;
193
204
  if (IsNumber(schema.exclusiveMinimumTimestamp))
194
205
  yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
@@ -199,10 +210,10 @@ var TypeCompiler;
199
210
  if (IsNumber(schema.maximumTimestamp))
200
211
  yield `${value}.getTime() <= ${schema.maximumTimestamp}`;
201
212
  }
202
- function* Function(schema, value) {
213
+ function* Function(schema, references, value) {
203
214
  yield `typeof ${value} === 'function'`;
204
215
  }
205
- function* Integer(schema, value) {
216
+ function* Integer(schema, references, value) {
206
217
  yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
207
218
  if (IsNumber(schema.multipleOf))
208
219
  yield `(${value} % ${schema.multipleOf}) === 0`;
@@ -215,28 +226,28 @@ var TypeCompiler;
215
226
  if (IsNumber(schema.maximum))
216
227
  yield `${value} <= ${schema.maximum}`;
217
228
  }
218
- function* Intersect(schema, value) {
229
+ function* Intersect(schema, references, value) {
219
230
  if (schema.unevaluatedProperties === undefined) {
220
- const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
231
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
221
232
  yield `${expressions.join(' && ')}`;
222
233
  }
223
234
  else if (schema.unevaluatedProperties === false) {
224
235
  // prettier-ignore
225
236
  const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', ');
226
- const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
237
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
227
238
  const expression1 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key))`;
228
239
  yield `${expressions.join(' && ')} && ${expression1}`;
229
240
  }
230
241
  else if (typeof schema.unevaluatedProperties === 'object') {
231
242
  // prettier-ignore
232
243
  const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', ');
233
- const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
234
- const expression1 = CreateExpression(schema.unevaluatedProperties, 'value[key]');
244
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
245
+ const expression1 = CreateExpression(schema.unevaluatedProperties, references, 'value[key]');
235
246
  const expression2 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key) || ${expression1})`;
236
247
  yield `${expressions.join(' && ')} && ${expression2}`;
237
248
  }
238
249
  }
239
- function* Literal(schema, value) {
250
+ function* Literal(schema, references, value) {
240
251
  if (typeof schema.const === 'number' || typeof schema.const === 'boolean') {
241
252
  yield `${value} === ${schema.const}`;
242
253
  }
@@ -244,18 +255,18 @@ var TypeCompiler;
244
255
  yield `${value} === '${schema.const}'`;
245
256
  }
246
257
  }
247
- function* Never(schema, value) {
258
+ function* Never(schema, references, value) {
248
259
  yield `false`;
249
260
  }
250
- function* Not(schema, value) {
251
- const left = CreateExpression(schema.allOf[0].not, value);
252
- const right = CreateExpression(schema.allOf[1], value);
261
+ function* Not(schema, references, value) {
262
+ const left = CreateExpression(schema.allOf[0].not, references, value);
263
+ const right = CreateExpression(schema.allOf[1], references, value);
253
264
  yield `!${left} && ${right}`;
254
265
  }
255
- function* Null(schema, value) {
266
+ function* Null(schema, references, value) {
256
267
  yield `${value} === null`;
257
268
  }
258
- function* Number(schema, value) {
269
+ function* Number(schema, references, value) {
259
270
  yield `typeof ${value} === 'number'`;
260
271
  if (!index_2.TypeSystem.AllowNaN)
261
272
  yield `Number.isFinite(${value})`;
@@ -270,8 +281,13 @@ var TypeCompiler;
270
281
  if (IsNumber(schema.maximum))
271
282
  yield `${value} <= ${schema.maximum}`;
272
283
  }
273
- function* Object(schema, value) {
274
- yield `(typeof ${value} === 'object' && ${value} !== null)`;
284
+ function* Object(schema, references, value) {
285
+ if (!index_2.TypeSystem.AllowArrayObjects) {
286
+ yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
287
+ }
288
+ else {
289
+ yield `(typeof ${value} === 'object' && ${value} !== null)`;
290
+ }
275
291
  if (!index_2.TypeSystem.AllowArrayObjects)
276
292
  yield `!Array.isArray(${value})`;
277
293
  if (IsNumber(schema.minProperties))
@@ -283,12 +299,12 @@ var TypeCompiler;
283
299
  const memberExpression = MemberExpression.Encode(value, schemaKey);
284
300
  const property = schema.properties[schemaKey];
285
301
  if (schema.required && schema.required.includes(schemaKey)) {
286
- yield* Visit(property, memberExpression);
302
+ yield* Visit(property, references, memberExpression);
287
303
  if (Types.ExtendsUndefined.Check(property))
288
304
  yield `('${schemaKey}' in ${value})`;
289
305
  }
290
306
  else {
291
- const expression = CreateExpression(property, memberExpression);
307
+ const expression = CreateExpression(property, references, memberExpression);
292
308
  yield `('${schemaKey}' in ${value} ? ${expression} : true)`;
293
309
  }
294
310
  }
@@ -302,37 +318,41 @@ var TypeCompiler;
302
318
  }
303
319
  }
304
320
  if (typeof schema.additionalProperties === 'object') {
305
- const expression = CreateExpression(schema.additionalProperties, 'value[key]');
321
+ const expression = CreateExpression(schema.additionalProperties, references, 'value[key]');
306
322
  const keys = `[${schemaKeys.map((key) => `'${key}'`).join(', ')}]`;
307
323
  yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
308
324
  }
309
325
  }
310
- function* Promise(schema, value) {
326
+ function* Promise(schema, references, value) {
311
327
  yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
312
328
  }
313
- function* Record(schema, value) {
314
- yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date))`;
329
+ function* Record(schema, references, value) {
330
+ yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`;
315
331
  if (!index_2.TypeSystem.AllowArrayObjects)
316
332
  yield `!Array.isArray(${value})`;
317
333
  const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
318
334
  const local = PushLocal(`new RegExp(/${keyPattern}/)`);
319
335
  yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`;
320
- const expression = CreateExpression(valueSchema, 'value');
336
+ const expression = CreateExpression(valueSchema, references, 'value');
321
337
  yield `Object.values(${value}).every(value => ${expression})`;
322
338
  }
323
- function* Ref(schema, value) {
339
+ function* Ref(schema, references, value) {
340
+ const index = references.findIndex((foreign) => foreign.$id === schema.$ref);
341
+ if (index === -1)
342
+ throw new TypeCompilerDereferenceError(schema);
343
+ const target = references[index];
324
344
  // Reference: If we have seen this reference before we can just yield and return
325
345
  // the function call. If this isn't the case we defer to visit to generate and
326
346
  // set the function for subsequent passes. Consider for refactor.
327
347
  if (state_local_function_names.has(schema.$ref))
328
348
  return yield `${CreateFunctionName(schema.$ref)}(${value})`;
329
- yield* Visit(Types.ReferenceRegistry.DerefOne(schema), value);
349
+ yield* Visit(target, references, value);
330
350
  }
331
- function* Self(schema, value) {
351
+ function* Self(schema, references, value) {
332
352
  const func = CreateFunctionName(schema.$ref);
333
353
  yield `${func}(${value})`;
334
354
  }
335
- function* String(schema, value) {
355
+ function* String(schema, references, value) {
336
356
  yield `(typeof ${value} === 'string')`;
337
357
  if (IsNumber(schema.minLength))
338
358
  yield `${value}.length >= ${schema.minLength}`;
@@ -346,37 +366,37 @@ var TypeCompiler;
346
366
  yield `format('${schema.format}', ${value})`;
347
367
  }
348
368
  }
349
- function* Symbol(schema, value) {
369
+ function* Symbol(schema, references, value) {
350
370
  yield `(typeof ${value} === 'symbol')`;
351
371
  }
352
- function* Tuple(schema, value) {
372
+ function* Tuple(schema, references, value) {
353
373
  yield `(Array.isArray(${value}))`;
354
374
  if (schema.items === undefined)
355
375
  return yield `${value}.length === 0`;
356
376
  yield `(${value}.length === ${schema.maxItems})`;
357
377
  for (let i = 0; i < schema.items.length; i++) {
358
- const expression = CreateExpression(schema.items[i], `${value}[${i}]`);
378
+ const expression = CreateExpression(schema.items[i], references, `${value}[${i}]`);
359
379
  yield `${expression}`;
360
380
  }
361
381
  }
362
- function* Undefined(schema, value) {
382
+ function* Undefined(schema, references, value) {
363
383
  yield `${value} === undefined`;
364
384
  }
365
- function* Union(schema, value) {
366
- const expressions = schema.anyOf.map((schema) => CreateExpression(schema, value));
385
+ function* Union(schema, references, value) {
386
+ const expressions = schema.anyOf.map((schema) => CreateExpression(schema, references, value));
367
387
  yield `(${expressions.join(' || ')})`;
368
388
  }
369
- function* Uint8Array(schema, value) {
389
+ function* Uint8Array(schema, references, value) {
370
390
  yield `${value} instanceof Uint8Array`;
371
391
  if (IsNumber(schema.maxByteLength))
372
392
  yield `(${value}.length <= ${schema.maxByteLength})`;
373
393
  if (IsNumber(schema.minByteLength))
374
394
  yield `(${value}.length >= ${schema.minByteLength})`;
375
395
  }
376
- function* Unknown(schema, value) {
396
+ function* Unknown(schema, references, value) {
377
397
  yield 'true';
378
398
  }
379
- function* Void(schema, value) {
399
+ function* Void(schema, references, value) {
380
400
  if (index_2.TypeSystem.AllowVoidNull) {
381
401
  yield `(${value} === undefined || ${value} === null)`;
382
402
  }
@@ -384,83 +404,84 @@ var TypeCompiler;
384
404
  yield `${value} === undefined`;
385
405
  }
386
406
  }
387
- function* UserDefined(schema, value) {
407
+ function* UserDefined(schema, references, value) {
388
408
  const schema_key = `schema_key_${state_remote_custom_types.size}`;
389
409
  state_remote_custom_types.set(schema_key, schema);
390
410
  yield `custom('${schema[Types.Kind]}', '${schema_key}', ${value})`;
391
411
  }
392
- function* Visit(schema, value) {
412
+ function* Visit(schema, references, value) {
413
+ const references_ = IsString(schema.$id) ? [...references, schema] : references;
414
+ const schema_ = schema;
393
415
  // Reference: Referenced schemas can originate from either additional schemas
394
416
  // or inline in the schema itself. Ideally the recursive path should align to
395
417
  // reference path. Consider for refactor.
396
- if (schema.$id && !state_local_function_names.has(schema.$id)) {
418
+ if (IsString(schema.$id) && !state_local_function_names.has(schema.$id)) {
397
419
  state_local_function_names.add(schema.$id);
398
420
  const name = CreateFunctionName(schema.$id);
399
- const body = CreateFunction(name, schema, 'value');
421
+ const body = CreateFunction(name, schema, references, 'value');
400
422
  PushFunction(body);
401
423
  yield `${name}(${value})`;
402
424
  return;
403
425
  }
404
- const anySchema = schema;
405
- switch (anySchema[Types.Kind]) {
426
+ switch (schema_[Types.Kind]) {
406
427
  case 'Any':
407
- return yield* Any(anySchema, value);
428
+ return yield* Any(schema_, references_, value);
408
429
  case 'Array':
409
- return yield* Array(anySchema, value);
430
+ return yield* Array(schema_, references_, value);
410
431
  case 'BigInt':
411
- return yield* BigInt(anySchema, value);
432
+ return yield* BigInt(schema_, references_, value);
412
433
  case 'Boolean':
413
- return yield* Boolean(anySchema, value);
434
+ return yield* Boolean(schema_, references_, value);
414
435
  case 'Constructor':
415
- return yield* Constructor(anySchema, value);
436
+ return yield* Constructor(schema_, references_, value);
416
437
  case 'Date':
417
- return yield* Date(anySchema, value);
438
+ return yield* Date(schema_, references_, value);
418
439
  case 'Function':
419
- return yield* Function(anySchema, value);
440
+ return yield* Function(schema_, references_, value);
420
441
  case 'Integer':
421
- return yield* Integer(anySchema, value);
442
+ return yield* Integer(schema_, references_, value);
422
443
  case 'Intersect':
423
- return yield* Intersect(anySchema, value);
444
+ return yield* Intersect(schema_, references_, value);
424
445
  case 'Literal':
425
- return yield* Literal(anySchema, value);
446
+ return yield* Literal(schema_, references_, value);
426
447
  case 'Never':
427
- return yield* Never(anySchema, value);
448
+ return yield* Never(schema_, references_, value);
428
449
  case 'Not':
429
- return yield* Not(anySchema, value);
450
+ return yield* Not(schema_, references_, value);
430
451
  case 'Null':
431
- return yield* Null(anySchema, value);
452
+ return yield* Null(schema_, references_, value);
432
453
  case 'Number':
433
- return yield* Number(anySchema, value);
454
+ return yield* Number(schema_, references_, value);
434
455
  case 'Object':
435
- return yield* Object(anySchema, value);
456
+ return yield* Object(schema_, references_, value);
436
457
  case 'Promise':
437
- return yield* Promise(anySchema, value);
458
+ return yield* Promise(schema_, references_, value);
438
459
  case 'Record':
439
- return yield* Record(anySchema, value);
460
+ return yield* Record(schema_, references_, value);
440
461
  case 'Ref':
441
- return yield* Ref(anySchema, value);
462
+ return yield* Ref(schema_, references_, value);
442
463
  case 'Self':
443
- return yield* Self(anySchema, value);
464
+ return yield* Self(schema_, references_, value);
444
465
  case 'String':
445
- return yield* String(anySchema, value);
466
+ return yield* String(schema_, references_, value);
446
467
  case 'Symbol':
447
- return yield* Symbol(anySchema, value);
468
+ return yield* Symbol(schema_, references_, value);
448
469
  case 'Tuple':
449
- return yield* Tuple(anySchema, value);
470
+ return yield* Tuple(schema_, references_, value);
450
471
  case 'Undefined':
451
- return yield* Undefined(anySchema, value);
472
+ return yield* Undefined(schema_, references_, value);
452
473
  case 'Union':
453
- return yield* Union(anySchema, value);
474
+ return yield* Union(schema_, references_, value);
454
475
  case 'Uint8Array':
455
- return yield* Uint8Array(anySchema, value);
476
+ return yield* Uint8Array(schema_, references_, value);
456
477
  case 'Unknown':
457
- return yield* Unknown(anySchema, value);
478
+ return yield* Unknown(schema_, references_, value);
458
479
  case 'Void':
459
- return yield* Void(anySchema, value);
480
+ return yield* Void(schema_, references_, value);
460
481
  default:
461
- if (!Types.TypeRegistry.Has(anySchema[Types.Kind]))
482
+ if (!Types.TypeRegistry.Has(schema_[Types.Kind]))
462
483
  throw new TypeCompilerUnknownTypeError(schema);
463
- return yield* UserDefined(anySchema, value);
484
+ return yield* UserDefined(schema_, references_, value);
464
485
  }
465
486
  }
466
487
  // -------------------------------------------------------------------
@@ -474,14 +495,14 @@ var TypeCompiler;
474
495
  state_local_function_names.clear();
475
496
  state_remote_custom_types.clear();
476
497
  }
477
- function CreateExpression(schema, value) {
478
- return `(${[...Visit(schema, value)].join(' && ')})`;
498
+ function CreateExpression(schema, references, value) {
499
+ return `(${[...Visit(schema, references, value)].join(' && ')})`;
479
500
  }
480
501
  function CreateFunctionName($id) {
481
502
  return `check_${Identifier.Encode($id)}`;
482
503
  }
483
- function CreateFunction(name, schema, value) {
484
- const expression = [...Visit(schema, value)].map((condition) => ` ${condition}`).join(' &&\n');
504
+ function CreateFunction(name, schema, references, value) {
505
+ const expression = [...Visit(schema, references, value)].map((condition) => ` ${condition}`).join(' &&\n');
485
506
  return `function ${name}(value) {\n return (\n${expression}\n )\n}`;
486
507
  }
487
508
  function PushFunction(functionBody) {
@@ -498,22 +519,25 @@ var TypeCompiler;
498
519
  // -------------------------------------------------------------------
499
520
  // Compile
500
521
  // -------------------------------------------------------------------
501
- function Build(schema) {
522
+ function Build(schema, references) {
502
523
  ResetCompiler();
503
- const check = CreateFunction('check', schema, 'value');
524
+ const check = CreateFunction('check', schema, references, 'value');
504
525
  const locals = GetLocals();
505
526
  return `${locals.join('\n')}\nreturn ${check}`;
506
527
  }
507
528
  /** Returns the generated assertion code used to validate this type. */
508
- function Code(schema) {
529
+ function Code(schema, references) {
509
530
  if (!Types.TypeGuard.TSchema(schema))
510
- throw new TypeCompilerPreflightCheckError(schema);
511
- return Build(schema);
531
+ throw new TypeCompilerTypeGuardError(schema);
532
+ for (const schema of references)
533
+ if (!Types.TypeGuard.TSchema(schema))
534
+ throw new TypeCompilerTypeGuardError(schema);
535
+ return Build(schema, references);
512
536
  }
513
537
  TypeCompiler.Code = Code;
514
538
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
515
- function Compile(schema) {
516
- const code = Code(schema);
539
+ function Compile(schema, references = []) {
540
+ const code = Code(schema, references);
517
541
  const custom_schemas = new Map(state_remote_custom_types);
518
542
  const compiledFunction = globalThis.Function('custom', 'format', 'hash', code);
519
543
  const checkFunction = compiledFunction((kind, schema_key, value) => {
@@ -530,7 +554,7 @@ var TypeCompiler;
530
554
  }, (value) => {
531
555
  return hash_1.ValueHash.Create(value);
532
556
  });
533
- return new TypeCheck(schema, checkFunction, code);
557
+ return new TypeCheck(schema, references, checkFunction, code);
534
558
  }
535
559
  TypeCompiler.Compile = Compile;
536
560
  })(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
@@ -78,7 +78,11 @@ export declare class ValueErrorsUnknownTypeError extends Error {
78
78
  readonly schema: Types.TSchema;
79
79
  constructor(schema: Types.TSchema);
80
80
  }
81
+ export declare class ValueErrorsDereferenceError extends Error {
82
+ readonly schema: Types.TRef | Types.TSelf;
83
+ constructor(schema: Types.TRef | Types.TSelf);
84
+ }
81
85
  /** Provides functionality to generate a sequence of errors against a TypeBox type. */
82
86
  export declare namespace ValueErrors {
83
- function Errors<T extends Types.TSchema>(schema: T, value: any): ValueErrorIterator;
87
+ function Errors<T extends Types.TSchema>(schema: T, references: Types.TSchema[], value: any): ValueErrorIterator;
84
88
  }