@sinclair/typebox 0.26.0-dev.4 → 0.26.0

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,34 @@ 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
+ }
167
+ // -------------------------------------------------------------------
168
+ // Overrides
169
+ // -------------------------------------------------------------------
170
+ function IsNumberCheck(value) {
171
+ return !index_2.TypeSystem.AllowNaN ? `(typeof ${value} === 'number' && Number.isFinite(${value}))` : `typeof ${value} === 'number'`;
172
+ }
173
+ function IsObjectCheck(value) {
174
+ return !index_2.TypeSystem.AllowArrayObjects ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)`;
175
+ }
176
+ function IsRecordCheck(value) {
177
+ return !index_2.TypeSystem.AllowArrayObjects
178
+ ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`
179
+ : `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`;
180
+ }
181
+ function IsVoidCheck(value) {
182
+ return index_2.TypeSystem.AllowVoidNull ? `(${value} === undefined || ${value} === null)` : `${value} === undefined`;
183
+ }
156
184
  // -------------------------------------------------------------------
157
185
  // Types
158
186
  // -------------------------------------------------------------------
159
- function* Any(schema, value) {
187
+ function* Any(schema, references, value) {
160
188
  yield 'true';
161
189
  }
162
- function* Array(schema, value) {
163
- const expression = CreateExpression(schema.items, 'value');
190
+ function* Array(schema, references, value) {
191
+ const expression = CreateExpression(schema.items, references, 'value');
164
192
  yield `Array.isArray(${value}) && ${value}.every(value => ${expression})`;
165
193
  if (IsNumber(schema.minItems))
166
194
  yield `${value}.length >= ${schema.minItems}`;
@@ -169,7 +197,7 @@ var TypeCompiler;
169
197
  if (schema.uniqueItems === true)
170
198
  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
199
  }
172
- function* BigInt(schema, value) {
200
+ function* BigInt(schema, references, value) {
173
201
  yield `(typeof ${value} === 'bigint')`;
174
202
  if (IsBigInt(schema.multipleOf))
175
203
  yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
@@ -182,13 +210,13 @@ var TypeCompiler;
182
210
  if (IsBigInt(schema.maximum))
183
211
  yield `${value} <= BigInt(${schema.maximum})`;
184
212
  }
185
- function* Boolean(schema, value) {
213
+ function* Boolean(schema, references, value) {
186
214
  yield `typeof ${value} === 'boolean'`;
187
215
  }
188
- function* Constructor(schema, value) {
189
- yield* Visit(schema.returns, `${value}.prototype`);
216
+ function* Constructor(schema, references, value) {
217
+ yield* Visit(schema.returns, references, `${value}.prototype`);
190
218
  }
191
- function* Date(schema, value) {
219
+ function* Date(schema, references, value) {
192
220
  yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`;
193
221
  if (IsNumber(schema.exclusiveMinimumTimestamp))
194
222
  yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
@@ -199,10 +227,10 @@ var TypeCompiler;
199
227
  if (IsNumber(schema.maximumTimestamp))
200
228
  yield `${value}.getTime() <= ${schema.maximumTimestamp}`;
201
229
  }
202
- function* Function(schema, value) {
230
+ function* Function(schema, references, value) {
203
231
  yield `typeof ${value} === 'function'`;
204
232
  }
205
- function* Integer(schema, value) {
233
+ function* Integer(schema, references, value) {
206
234
  yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
207
235
  if (IsNumber(schema.multipleOf))
208
236
  yield `(${value} % ${schema.multipleOf}) === 0`;
@@ -215,28 +243,28 @@ var TypeCompiler;
215
243
  if (IsNumber(schema.maximum))
216
244
  yield `${value} <= ${schema.maximum}`;
217
245
  }
218
- function* Intersect(schema, value) {
246
+ function* Intersect(schema, references, value) {
219
247
  if (schema.unevaluatedProperties === undefined) {
220
- const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
248
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
221
249
  yield `${expressions.join(' && ')}`;
222
250
  }
223
251
  else if (schema.unevaluatedProperties === false) {
224
252
  // prettier-ignore
225
253
  const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', ');
226
- const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
254
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
227
255
  const expression1 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key))`;
228
256
  yield `${expressions.join(' && ')} && ${expression1}`;
229
257
  }
230
258
  else if (typeof schema.unevaluatedProperties === 'object') {
231
259
  // prettier-ignore
232
260
  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]');
261
+ const expressions = schema.allOf.map((schema) => CreateExpression(schema, references, value));
262
+ const expression1 = CreateExpression(schema.unevaluatedProperties, references, 'value[key]');
235
263
  const expression2 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key) || ${expression1})`;
236
264
  yield `${expressions.join(' && ')} && ${expression2}`;
237
265
  }
238
266
  }
239
- function* Literal(schema, value) {
267
+ function* Literal(schema, references, value) {
240
268
  if (typeof schema.const === 'number' || typeof schema.const === 'boolean') {
241
269
  yield `${value} === ${schema.const}`;
242
270
  }
@@ -244,21 +272,19 @@ var TypeCompiler;
244
272
  yield `${value} === '${schema.const}'`;
245
273
  }
246
274
  }
247
- function* Never(schema, value) {
275
+ function* Never(schema, references, value) {
248
276
  yield `false`;
249
277
  }
250
- function* Not(schema, value) {
251
- const left = CreateExpression(schema.allOf[0].not, value);
252
- const right = CreateExpression(schema.allOf[1], value);
278
+ function* Not(schema, references, value) {
279
+ const left = CreateExpression(schema.allOf[0].not, references, value);
280
+ const right = CreateExpression(schema.allOf[1], references, value);
253
281
  yield `!${left} && ${right}`;
254
282
  }
255
- function* Null(schema, value) {
283
+ function* Null(schema, references, value) {
256
284
  yield `${value} === null`;
257
285
  }
258
- function* Number(schema, value) {
259
- yield `typeof ${value} === 'number'`;
260
- if (!index_2.TypeSystem.AllowNaN)
261
- yield `Number.isFinite(${value})`;
286
+ function* Number(schema, references, value) {
287
+ yield IsNumberCheck(value);
262
288
  if (IsNumber(schema.multipleOf))
263
289
  yield `(${value} % ${schema.multipleOf}) === 0`;
264
290
  if (IsNumber(schema.exclusiveMinimum))
@@ -270,8 +296,8 @@ var TypeCompiler;
270
296
  if (IsNumber(schema.maximum))
271
297
  yield `${value} <= ${schema.maximum}`;
272
298
  }
273
- function* Object(schema, value) {
274
- yield `(typeof ${value} === 'object' && ${value} !== null)`;
299
+ function* Object(schema, references, value) {
300
+ yield IsObjectCheck(value);
275
301
  if (!index_2.TypeSystem.AllowArrayObjects)
276
302
  yield `!Array.isArray(${value})`;
277
303
  if (IsNumber(schema.minProperties))
@@ -283,12 +309,12 @@ var TypeCompiler;
283
309
  const memberExpression = MemberExpression.Encode(value, schemaKey);
284
310
  const property = schema.properties[schemaKey];
285
311
  if (schema.required && schema.required.includes(schemaKey)) {
286
- yield* Visit(property, memberExpression);
312
+ yield* Visit(property, references, memberExpression);
287
313
  if (Types.ExtendsUndefined.Check(property))
288
314
  yield `('${schemaKey}' in ${value})`;
289
315
  }
290
316
  else {
291
- const expression = CreateExpression(property, memberExpression);
317
+ const expression = CreateExpression(property, references, memberExpression);
292
318
  yield `('${schemaKey}' in ${value} ? ${expression} : true)`;
293
319
  }
294
320
  }
@@ -302,37 +328,39 @@ var TypeCompiler;
302
328
  }
303
329
  }
304
330
  if (typeof schema.additionalProperties === 'object') {
305
- const expression = CreateExpression(schema.additionalProperties, 'value[key]');
331
+ const expression = CreateExpression(schema.additionalProperties, references, 'value[key]');
306
332
  const keys = `[${schemaKeys.map((key) => `'${key}'`).join(', ')}]`;
307
333
  yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
308
334
  }
309
335
  }
310
- function* Promise(schema, value) {
336
+ function* Promise(schema, references, value) {
311
337
  yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
312
338
  }
313
- function* Record(schema, value) {
314
- yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date))`;
315
- if (!index_2.TypeSystem.AllowArrayObjects)
316
- yield `!Array.isArray(${value})`;
339
+ function* Record(schema, references, value) {
340
+ yield IsRecordCheck(value);
317
341
  const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
318
342
  const local = PushLocal(`new RegExp(/${keyPattern}/)`);
319
343
  yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`;
320
- const expression = CreateExpression(valueSchema, 'value');
344
+ const expression = CreateExpression(valueSchema, references, 'value');
321
345
  yield `Object.values(${value}).every(value => ${expression})`;
322
346
  }
323
- function* Ref(schema, value) {
347
+ function* Ref(schema, references, value) {
348
+ const index = references.findIndex((foreign) => foreign.$id === schema.$ref);
349
+ if (index === -1)
350
+ throw new TypeCompilerDereferenceError(schema);
351
+ const target = references[index];
324
352
  // Reference: If we have seen this reference before we can just yield and return
325
353
  // the function call. If this isn't the case we defer to visit to generate and
326
354
  // set the function for subsequent passes. Consider for refactor.
327
355
  if (state_local_function_names.has(schema.$ref))
328
356
  return yield `${CreateFunctionName(schema.$ref)}(${value})`;
329
- yield* Visit(Types.ReferenceRegistry.DerefOne(schema), value);
357
+ yield* Visit(target, references, value);
330
358
  }
331
- function* Self(schema, value) {
359
+ function* Self(schema, references, value) {
332
360
  const func = CreateFunctionName(schema.$ref);
333
361
  yield `${func}(${value})`;
334
362
  }
335
- function* String(schema, value) {
363
+ function* String(schema, references, value) {
336
364
  yield `(typeof ${value} === 'string')`;
337
365
  if (IsNumber(schema.minLength))
338
366
  yield `${value}.length >= ${schema.minLength}`;
@@ -346,121 +374,117 @@ var TypeCompiler;
346
374
  yield `format('${schema.format}', ${value})`;
347
375
  }
348
376
  }
349
- function* Symbol(schema, value) {
377
+ function* Symbol(schema, references, value) {
350
378
  yield `(typeof ${value} === 'symbol')`;
351
379
  }
352
- function* Tuple(schema, value) {
380
+ function* Tuple(schema, references, value) {
353
381
  yield `(Array.isArray(${value}))`;
354
382
  if (schema.items === undefined)
355
383
  return yield `${value}.length === 0`;
356
384
  yield `(${value}.length === ${schema.maxItems})`;
357
385
  for (let i = 0; i < schema.items.length; i++) {
358
- const expression = CreateExpression(schema.items[i], `${value}[${i}]`);
386
+ const expression = CreateExpression(schema.items[i], references, `${value}[${i}]`);
359
387
  yield `${expression}`;
360
388
  }
361
389
  }
362
- function* Undefined(schema, value) {
390
+ function* Undefined(schema, references, value) {
363
391
  yield `${value} === undefined`;
364
392
  }
365
- function* Union(schema, value) {
366
- const expressions = schema.anyOf.map((schema) => CreateExpression(schema, value));
393
+ function* Union(schema, references, value) {
394
+ const expressions = schema.anyOf.map((schema) => CreateExpression(schema, references, value));
367
395
  yield `(${expressions.join(' || ')})`;
368
396
  }
369
- function* Uint8Array(schema, value) {
397
+ function* Uint8Array(schema, references, value) {
370
398
  yield `${value} instanceof Uint8Array`;
371
399
  if (IsNumber(schema.maxByteLength))
372
400
  yield `(${value}.length <= ${schema.maxByteLength})`;
373
401
  if (IsNumber(schema.minByteLength))
374
402
  yield `(${value}.length >= ${schema.minByteLength})`;
375
403
  }
376
- function* Unknown(schema, value) {
404
+ function* Unknown(schema, references, value) {
377
405
  yield 'true';
378
406
  }
379
- function* Void(schema, value) {
380
- if (index_2.TypeSystem.AllowVoidNull) {
381
- yield `(${value} === undefined || ${value} === null)`;
382
- }
383
- else {
384
- yield `${value} === undefined`;
385
- }
407
+ function* Void(schema, references, value) {
408
+ yield IsVoidCheck(value);
386
409
  }
387
- function* UserDefined(schema, value) {
410
+ function* UserDefined(schema, references, value) {
388
411
  const schema_key = `schema_key_${state_remote_custom_types.size}`;
389
412
  state_remote_custom_types.set(schema_key, schema);
390
413
  yield `custom('${schema[Types.Kind]}', '${schema_key}', ${value})`;
391
414
  }
392
- function* Visit(schema, value) {
415
+ function* Visit(schema, references, value) {
416
+ const references_ = IsString(schema.$id) ? [...references, schema] : references;
417
+ const schema_ = schema;
393
418
  // Reference: Referenced schemas can originate from either additional schemas
394
419
  // or inline in the schema itself. Ideally the recursive path should align to
395
420
  // reference path. Consider for refactor.
396
- if (schema.$id && !state_local_function_names.has(schema.$id)) {
421
+ if (IsString(schema.$id) && !state_local_function_names.has(schema.$id)) {
397
422
  state_local_function_names.add(schema.$id);
398
423
  const name = CreateFunctionName(schema.$id);
399
- const body = CreateFunction(name, schema, 'value');
424
+ const body = CreateFunction(name, schema, references, 'value');
400
425
  PushFunction(body);
401
426
  yield `${name}(${value})`;
402
427
  return;
403
428
  }
404
- const anySchema = schema;
405
- switch (anySchema[Types.Kind]) {
429
+ switch (schema_[Types.Kind]) {
406
430
  case 'Any':
407
- return yield* Any(anySchema, value);
431
+ return yield* Any(schema_, references_, value);
408
432
  case 'Array':
409
- return yield* Array(anySchema, value);
433
+ return yield* Array(schema_, references_, value);
410
434
  case 'BigInt':
411
- return yield* BigInt(anySchema, value);
435
+ return yield* BigInt(schema_, references_, value);
412
436
  case 'Boolean':
413
- return yield* Boolean(anySchema, value);
437
+ return yield* Boolean(schema_, references_, value);
414
438
  case 'Constructor':
415
- return yield* Constructor(anySchema, value);
439
+ return yield* Constructor(schema_, references_, value);
416
440
  case 'Date':
417
- return yield* Date(anySchema, value);
441
+ return yield* Date(schema_, references_, value);
418
442
  case 'Function':
419
- return yield* Function(anySchema, value);
443
+ return yield* Function(schema_, references_, value);
420
444
  case 'Integer':
421
- return yield* Integer(anySchema, value);
445
+ return yield* Integer(schema_, references_, value);
422
446
  case 'Intersect':
423
- return yield* Intersect(anySchema, value);
447
+ return yield* Intersect(schema_, references_, value);
424
448
  case 'Literal':
425
- return yield* Literal(anySchema, value);
449
+ return yield* Literal(schema_, references_, value);
426
450
  case 'Never':
427
- return yield* Never(anySchema, value);
451
+ return yield* Never(schema_, references_, value);
428
452
  case 'Not':
429
- return yield* Not(anySchema, value);
453
+ return yield* Not(schema_, references_, value);
430
454
  case 'Null':
431
- return yield* Null(anySchema, value);
455
+ return yield* Null(schema_, references_, value);
432
456
  case 'Number':
433
- return yield* Number(anySchema, value);
457
+ return yield* Number(schema_, references_, value);
434
458
  case 'Object':
435
- return yield* Object(anySchema, value);
459
+ return yield* Object(schema_, references_, value);
436
460
  case 'Promise':
437
- return yield* Promise(anySchema, value);
461
+ return yield* Promise(schema_, references_, value);
438
462
  case 'Record':
439
- return yield* Record(anySchema, value);
463
+ return yield* Record(schema_, references_, value);
440
464
  case 'Ref':
441
- return yield* Ref(anySchema, value);
465
+ return yield* Ref(schema_, references_, value);
442
466
  case 'Self':
443
- return yield* Self(anySchema, value);
467
+ return yield* Self(schema_, references_, value);
444
468
  case 'String':
445
- return yield* String(anySchema, value);
469
+ return yield* String(schema_, references_, value);
446
470
  case 'Symbol':
447
- return yield* Symbol(anySchema, value);
471
+ return yield* Symbol(schema_, references_, value);
448
472
  case 'Tuple':
449
- return yield* Tuple(anySchema, value);
473
+ return yield* Tuple(schema_, references_, value);
450
474
  case 'Undefined':
451
- return yield* Undefined(anySchema, value);
475
+ return yield* Undefined(schema_, references_, value);
452
476
  case 'Union':
453
- return yield* Union(anySchema, value);
477
+ return yield* Union(schema_, references_, value);
454
478
  case 'Uint8Array':
455
- return yield* Uint8Array(anySchema, value);
479
+ return yield* Uint8Array(schema_, references_, value);
456
480
  case 'Unknown':
457
- return yield* Unknown(anySchema, value);
481
+ return yield* Unknown(schema_, references_, value);
458
482
  case 'Void':
459
- return yield* Void(anySchema, value);
483
+ return yield* Void(schema_, references_, value);
460
484
  default:
461
- if (!Types.TypeRegistry.Has(anySchema[Types.Kind]))
485
+ if (!Types.TypeRegistry.Has(schema_[Types.Kind]))
462
486
  throw new TypeCompilerUnknownTypeError(schema);
463
- return yield* UserDefined(anySchema, value);
487
+ return yield* UserDefined(schema_, references_, value);
464
488
  }
465
489
  }
466
490
  // -------------------------------------------------------------------
@@ -474,14 +498,14 @@ var TypeCompiler;
474
498
  state_local_function_names.clear();
475
499
  state_remote_custom_types.clear();
476
500
  }
477
- function CreateExpression(schema, value) {
478
- return `(${[...Visit(schema, value)].join(' && ')})`;
501
+ function CreateExpression(schema, references, value) {
502
+ return `(${[...Visit(schema, references, value)].join(' && ')})`;
479
503
  }
480
504
  function CreateFunctionName($id) {
481
505
  return `check_${Identifier.Encode($id)}`;
482
506
  }
483
- function CreateFunction(name, schema, value) {
484
- const expression = [...Visit(schema, value)].map((condition) => ` ${condition}`).join(' &&\n');
507
+ function CreateFunction(name, schema, references, value) {
508
+ const expression = [...Visit(schema, references, value)].map((condition) => ` ${condition}`).join(' &&\n');
485
509
  return `function ${name}(value) {\n return (\n${expression}\n )\n}`;
486
510
  }
487
511
  function PushFunction(functionBody) {
@@ -498,22 +522,25 @@ var TypeCompiler;
498
522
  // -------------------------------------------------------------------
499
523
  // Compile
500
524
  // -------------------------------------------------------------------
501
- function Build(schema) {
525
+ function Build(schema, references) {
502
526
  ResetCompiler();
503
- const check = CreateFunction('check', schema, 'value');
527
+ const check = CreateFunction('check', schema, references, 'value');
504
528
  const locals = GetLocals();
505
529
  return `${locals.join('\n')}\nreturn ${check}`;
506
530
  }
507
531
  /** Returns the generated assertion code used to validate this type. */
508
- function Code(schema) {
532
+ function Code(schema, references = []) {
509
533
  if (!Types.TypeGuard.TSchema(schema))
510
- throw new TypeCompilerPreflightCheckError(schema);
511
- return Build(schema);
534
+ throw new TypeCompilerTypeGuardError(schema);
535
+ for (const schema of references)
536
+ if (!Types.TypeGuard.TSchema(schema))
537
+ throw new TypeCompilerTypeGuardError(schema);
538
+ return Build(schema, references);
512
539
  }
513
540
  TypeCompiler.Code = Code;
514
541
  /** 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);
542
+ function Compile(schema, references = []) {
543
+ const code = Code(schema, references);
517
544
  const custom_schemas = new Map(state_remote_custom_types);
518
545
  const compiledFunction = globalThis.Function('custom', 'format', 'hash', code);
519
546
  const checkFunction = compiledFunction((kind, schema_key, value) => {
@@ -530,7 +557,7 @@ var TypeCompiler;
530
557
  }, (value) => {
531
558
  return hash_1.ValueHash.Create(value);
532
559
  });
533
- return new TypeCheck(schema, checkFunction, code);
560
+ return new TypeCheck(schema, references, checkFunction, code);
534
561
  }
535
562
  TypeCompiler.Compile = Compile;
536
563
  })(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
  }