@sinclair/typebox 0.26.0-dev → 0.26.0-dev.2

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.
@@ -1,15 +1,15 @@
1
1
  import * as Types from '../typebox';
2
- import { ValueError } from '../errors/index';
2
+ 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
6
  private readonly checkFunc;
7
7
  private readonly code;
8
8
  constructor(schema: T, checkFunc: CheckFunction, code: string);
9
- /** Returns the generated validation code used to validate this type. */
9
+ /** Returns the generated assertion code used to validate this type. */
10
10
  Code(): string;
11
11
  /** Returns an iterator for each error in this value. */
12
- Errors(value: unknown): IterableIterator<ValueError>;
12
+ Errors(value: unknown): ValueErrorIterator;
13
13
  /** Returns true if the value matches the compiled type. */
14
14
  Check(value: unknown): value is Types.Static<T>;
15
15
  }
@@ -26,7 +26,7 @@ export declare class TypeCompilerPreflightCheckError extends Error {
26
26
  }
27
27
  /** Compiles Types for Runtime Type Checking */
28
28
  export declare namespace TypeCompiler {
29
- /** Returns the generated validation code used to validate this type. */
29
+ /** Returns the generated assertion code used to validate this type. */
30
30
  function Code<T extends Types.TSchema>(schema: T): string;
31
31
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
32
32
  function Compile<T extends Types.TSchema>(schema: T): TypeCheck<T>;
@@ -41,7 +41,7 @@ class TypeCheck {
41
41
  this.checkFunc = checkFunc;
42
42
  this.code = code;
43
43
  }
44
- /** Returns the generated validation code used to validate this type. */
44
+ /** Returns the generated assertion code used to validate this type. */
45
45
  Code() {
46
46
  return this.code;
47
47
  }
@@ -504,7 +504,7 @@ var TypeCompiler;
504
504
  const locals = GetLocals();
505
505
  return `${locals.join('\n')}\nreturn ${check}`;
506
506
  }
507
- /** Returns the generated validation code used to validate this type. */
507
+ /** Returns the generated assertion code used to validate this type. */
508
508
  function Code(schema) {
509
509
  if (!Types.TypeGuard.TSchema(schema))
510
510
  throw new TypeCompilerPreflightCheckError(schema);
@@ -67,11 +67,18 @@ export interface ValueError {
67
67
  value: unknown;
68
68
  message: string;
69
69
  }
70
+ export declare class ValueErrorIterator {
71
+ private readonly iterator;
72
+ constructor(iterator: IterableIterator<ValueError>);
73
+ [Symbol.iterator](): IterableIterator<ValueError>;
74
+ /** Returns the first value error or undefined if no errors */
75
+ First(): ValueError | undefined;
76
+ }
70
77
  export declare class ValueErrorsUnknownTypeError extends Error {
71
78
  readonly schema: Types.TSchema;
72
79
  constructor(schema: Types.TSchema);
73
80
  }
74
81
  /** Provides functionality to generate a sequence of errors against a TypeBox type. */
75
82
  export declare namespace ValueErrors {
76
- function Errors<T extends Types.TSchema>(schema: T, value: any): IterableIterator<ValueError>;
83
+ function Errors<T extends Types.TSchema>(schema: T, value: any): ValueErrorIterator;
77
84
  }
package/errors/errors.js CHANGED
@@ -1,4 +1,6 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorIterator = exports.ValueErrorType = void 0;
2
4
  /*--------------------------------------------------------------------------
3
5
 
4
6
  @sinclair/typebox/errors
@@ -26,8 +28,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
28
  THE SOFTWARE.
27
29
 
28
30
  ---------------------------------------------------------------------------*/
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
31
31
  const Types = require("../typebox");
32
32
  const index_1 = require("../system/index");
33
33
  const hash_1 = require("../value/hash");
@@ -97,6 +97,23 @@ var ValueErrorType;
97
97
  ValueErrorType[ValueErrorType["Custom"] = 58] = "Custom";
98
98
  })(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
99
99
  // -------------------------------------------------------------------
100
+ // ValueErrorIterator
101
+ // -------------------------------------------------------------------
102
+ class ValueErrorIterator {
103
+ constructor(iterator) {
104
+ this.iterator = iterator;
105
+ }
106
+ [Symbol.iterator]() {
107
+ return this.iterator;
108
+ }
109
+ /** Returns the first value error or undefined if no errors */
110
+ First() {
111
+ const next = this.iterator.next();
112
+ return next.done ? undefined : next.value;
113
+ }
114
+ }
115
+ exports.ValueErrorIterator = ValueErrorIterator;
116
+ // -------------------------------------------------------------------
100
117
  // ValueErrors
101
118
  // -------------------------------------------------------------------
102
119
  class ValueErrorsUnknownTypeError extends Error {
@@ -546,8 +563,8 @@ var ValueErrors;
546
563
  return yield* UserDefined(anySchema, path, value);
547
564
  }
548
565
  }
549
- function* Errors(schema, value) {
550
- yield* Visit(schema, '', value);
566
+ function Errors(schema, value) {
567
+ return new ValueErrorIterator(Visit(schema, '', value));
551
568
  }
552
569
  ValueErrors.Errors = Errors;
553
570
  })(ValueErrors = exports.ValueErrors || (exports.ValueErrors = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.26.0-dev",
3
+ "version": "0.26.0-dev.2",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -586,9 +586,9 @@ TypeBox provides property modifier types that allow properties to be mapped with
586
586
  │ const T = Type.Object({ │ type T = { │ const T = { │
587
587
  │ name: Type.Optional( │ name?: string │ type: 'object', │
588
588
  │ Type.String() │ } │ properties: { │
589
- │ ) │ │ name: {
590
- │ }) │ │ type: 'string'
591
- │ │ │ }
589
+ │ ) │ │ name: {
590
+ │ }) │ │ type: 'string'
591
+ │ │ │ }
592
592
  │ │ │ } │
593
593
  │ │ │ } │
594
594
  │ │ │ │
@@ -777,7 +777,7 @@ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
777
777
  type T = Static<typeof T> // type T = string
778
778
  ```
779
779
 
780
- The `Type.Unsafe(...)` type allows specific or non-standard OpenAPI schematics can be constructed.
780
+ The `Type.Unsafe(...)` type allows for the expression of specific OpenAPI schema representations.
781
781
 
782
782
  ```typescript
783
783
  import { Type, Static, TSchema } from '@sinclair/typebox'
@@ -812,7 +812,7 @@ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
812
812
 
813
813
  ### Guards
814
814
 
815
- TypeBox provides a `TypeGuard` module used for type value assertions and reflection.
815
+ TypeBox provides a `TypeGuard` module for reflection and type assertion.
816
816
 
817
817
  ```typescript
818
818
  import { Type, TypeGuard } from '@sinclair/typebox'
@@ -1029,15 +1029,15 @@ ValuePointer.Set(A, '/z', 1) // const A = { x: 1, y: 1,
1029
1029
 
1030
1030
  ## TypeCheck
1031
1031
 
1032
- TypeBox types targets JSON Schema draft 6 so is immediately compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for high performance compilation and value assertion.
1032
+ TypeBox types target JSON Schema draft 6 so are compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for high performance compilation and value assertion.
1033
1033
 
1034
- The following details using both Ajv and TypeBox's compiler infrastructure.
1034
+ The following sections detail using Ajv and TypeBox's compiler infrastructure.
1035
1035
 
1036
1036
  <a name='typecheck-ajv'></a>
1037
1037
 
1038
1038
  ## Ajv
1039
1039
 
1040
- The following shows the recommended setup for Ajv with additional string formats.
1040
+ The following shows the recommended setup for Ajv.
1041
1041
 
1042
1042
  ```bash
1043
1043
  $ npm install ajv ajv-formats --save
@@ -1078,7 +1078,7 @@ const R = C({ x: 1, y: 2, z: 3 }) // const R = true
1078
1078
 
1079
1079
  ### TypeCompiler
1080
1080
 
1081
- The TypeBox TypeCompiler is a high performance JIT compiler that compiles TypeBox types into optimized JavaScript validation routines. The compiler is tuned both for fast compilation and value assertion. It is designed primarily for integrating into application frameworks but can also be used as a general purpose validator.
1081
+ The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast value assertion. It is designed to serve as a validation backend that can be integrated into larger applications; but can also be used as a general purpose validator.
1082
1082
 
1083
1083
  The TypeCompiler is provided as an optional import.
1084
1084
 
@@ -1098,7 +1098,7 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
1098
1098
  const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
1099
1099
  ```
1100
1100
 
1101
- Use the `Errors(...)` function to produce diagnostics for a value. The `Errors(...)` function will return an iterator that will perform an exhaustive check across the value and yield any error found. For performance, this function should only be called after failed `Check(...)`.
1101
+ Use the `Errors(...)` function to produce diagnostic errors for a value. The `Errors(...)` function will return an iterator that if enumerated; will perform an exhaustive check across the entire value and yield any error found. For performance, this function should only be called after failed `Check(...)`. Applications may also choose to yield only the first value to avoid exhaustive error generation.
1102
1102
 
1103
1103
  ```typescript
1104
1104
  const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
@@ -1181,7 +1181,7 @@ const R = Value.Check(T, { x: 1, y: 2 }) // const R = true
1181
1181
 
1182
1182
  ### Formats
1183
1183
 
1184
- Use the `Format(...)` function to create a custom string formats. The following creates a custom string format that checks for lowercase strings.
1184
+ Use the `Format(...)` function to create a custom string format. The following creates a custom string format that checks for lowercase strings.
1185
1185
 
1186
1186
  ```typescript
1187
1187
  TypeSystem.Format('lowercase', value => value === value.toLowerCase()) // format should be lowercase
package/typebox.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export declare const Kind: unique symbol;
2
2
  export declare const Hint: unique symbol;
3
3
  export declare const Modifier: unique symbol;
4
+ export declare const Recursive: unique symbol;
4
5
  export type TupleToIntersect<T extends any[]> = T extends [infer I] ? I : T extends [infer I, ...infer R] ? I & TupleToIntersect<R> : never;
5
6
  export type TupleToUnion<T extends any[]> = {
6
7
  [K in keyof T]: T[K];
@@ -41,8 +42,9 @@ export interface TKind {
41
42
  [Kind]: string;
42
43
  }
43
44
  export interface TSchema extends SchemaOptions, TKind {
44
- [Hint]?: string;
45
45
  [Modifier]?: string;
46
+ [Recursive]?: string;
47
+ [Hint]?: string;
46
48
  params: unknown[];
47
49
  static: unknown;
48
50
  }
@@ -170,7 +172,7 @@ export type TKeyOfTuple<T extends TSchema> = {
170
172
  } extends infer U ? UnionToTuple<Exclude<{
171
173
  [K in keyof U]: U[K];
172
174
  }[keyof U], undefined>> : never;
173
- export type TKeyOf<T extends TSchema = TSchema> = (T extends TIntersect ? TKeyOfTuple<T> : T extends TUnion ? TKeyOfTuple<T> : T extends TObject ? TKeyOfTuple<T> : [
175
+ export type TKeyOf<T extends TSchema = TSchema, D = TDeref<T>> = (D extends TIntersect ? TKeyOfTuple<T> : D extends TUnion ? TKeyOfTuple<T> : D extends TObject ? TKeyOfTuple<T> : [
174
176
  ]) extends infer R ? R extends [] ? TNever : TUnion<Assert<R, TSchema[]>> : never;
175
177
  export type TLiteralValue = string | number | boolean | bigint;
176
178
  export interface TLiteral<T extends TLiteralValue = TLiteralValue> extends TSchema {
@@ -242,7 +244,7 @@ export type TOmitArray<T extends TSchema[], K extends keyof any> = Assert<{
242
244
  [K2 in keyof T]: TOmit<Assert<T[K2], TSchema>, K>;
243
245
  }, TSchema[]>;
244
246
  export type TOmitProperties<T extends TProperties, K extends keyof any> = Evaluate<Assert<Omit<T, K>, TProperties>>;
245
- export type TOmit<T extends TSchema, K extends keyof any> = T extends TIntersect<infer S> ? TIntersect<TOmitArray<S, K>> : T extends TUnion<infer S> ? TUnion<TOmitArray<S, K>> : T extends TObject<infer S> ? TObject<TOmitProperties<S, K>> : T;
247
+ export type TOmit<T extends TSchema, K extends keyof any, D = TDeref<T>> = D extends TIntersect<infer S> ? TIntersect<TOmitArray<S, K>> : D extends TUnion<infer S> ? TUnion<TOmitArray<S, K>> : D extends TObject<infer S> ? TObject<TOmitProperties<S, K>> : D;
246
248
  export type TParameters<T extends TFunction> = TTuple<T['parameters']>;
247
249
  export type TPartialArray<T extends TSchema[]> = Assert<{
248
250
  [K in keyof T]: TPartial<Assert<T[K], TSchema>>;
@@ -250,14 +252,14 @@ export type TPartialArray<T extends TSchema[]> = Assert<{
250
252
  export type TPartialProperties<T extends TProperties> = Evaluate<Assert<{
251
253
  [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonlyOptional<U> : T[K] extends TReadonly<infer U> ? TReadonlyOptional<U> : T[K] extends TOptional<infer U> ? TOptional<U> : TOptional<T[K]>;
252
254
  }, TProperties>>;
253
- export type TPartial<T extends TSchema> = T extends TIntersect<infer S> ? TIntersect<TPartialArray<S>> : T extends TUnion<infer S> ? TUnion<TPartialArray<S>> : T extends TObject<infer S> ? TObject<TPartialProperties<S>> : T;
255
+ export type TPartial<T extends TSchema, D = TDeref<T>> = D extends TIntersect<infer S> ? TIntersect<TPartialArray<S>> : D extends TUnion<infer S> ? TUnion<TPartialArray<S>> : D extends TObject<infer S> ? TObject<TPartialProperties<S>> : D;
254
256
  export type TPickArray<T extends TSchema[], K extends keyof any> = {
255
257
  [K2 in keyof T]: TPick<Assert<T[K2], TSchema>, K>;
256
258
  };
257
259
  export type TPickProperties<T extends TProperties, K extends keyof any> = Pick<T, Assert<Extract<K, keyof T>, keyof T>> extends infer R ? ({
258
260
  [K in keyof R]: Assert<R[K], TSchema> extends TSchema ? R[K] : never;
259
261
  }) : never;
260
- export type TPick<T extends TSchema, K extends keyof any> = T extends TIntersect<infer S> ? TIntersect<TPickArray<S, K>> : T extends TUnion<infer S> ? TUnion<TPickArray<S, K>> : T extends TObject<infer S> ? TObject<TPickProperties<S, K>> : T;
262
+ export type TPick<T extends TSchema, K extends keyof any, D = TDeref<T>> = D extends TIntersect<infer S> ? TIntersect<TPickArray<S, K>> : D extends TUnion<infer S> ? TUnion<TPickArray<S, K>> : D extends TObject<infer S> ? TObject<TPickProperties<S, K>> : D;
261
263
  export type TPromiseStatic<T extends TSchema, P extends unknown[]> = Promise<Static<T, P>>;
262
264
  export interface TPromise<T extends TSchema = TSchema> extends TSchema {
263
265
  [Kind]: 'Promise';
@@ -305,7 +307,7 @@ export type TRequiredArray<T extends TSchema[]> = Assert<{
305
307
  export type TRequiredProperties<T extends TProperties> = Evaluate<Assert<{
306
308
  [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonly<U> : T[K] extends TReadonly<infer U> ? TReadonly<U> : T[K] extends TOptional<infer U> ? U : T[K];
307
309
  }, TProperties>>;
308
- export type TRequired<T extends TSchema> = T extends TIntersect<infer S> ? TIntersect<TRequiredArray<S>> : T extends TUnion<infer S> ? TUnion<TRequiredArray<S>> : T extends TObject<infer S> ? TObject<TRequiredProperties<S>> : T;
310
+ export type TRequired<T extends TSchema, D = TDeref<T>> = D extends TIntersect<infer S> ? TIntersect<TRequiredArray<S>> : D extends TUnion<infer S> ? TUnion<TRequiredArray<S>> : D extends TObject<infer S> ? TObject<TRequiredProperties<S>> : D;
309
311
  export type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex';
310
312
  export interface StringOptions<Format extends string> extends SchemaOptions {
311
313
  minLength?: number;
@@ -507,9 +509,10 @@ export declare enum TypeExtendsResult {
507
509
  export declare namespace TypeExtends {
508
510
  function Extends(left: TSchema, right: TSchema): TypeExtendsResult;
509
511
  }
510
- /** Specialized Clone for Types. */
512
+ /** Specialized Clone for Types. Clones and removes non self-referential identifiers */
511
513
  export declare namespace TypeClone {
512
- function Clone<T extends TSchema | TProperties>(schema: T, options: SchemaOptions): T;
514
+ /** Clones a type. This function will omit non-self referential identifiers on the cloned type. */
515
+ function Clone<T extends TSchema>(schema: T, options: SchemaOptions): T;
513
516
  }
514
517
  export declare namespace ObjectMap {
515
518
  function Map<T = TSchema>(schema: TSchema, callback: (object: TObject) => TObject, options: SchemaOptions): T;
@@ -542,11 +545,11 @@ export declare class StandardTypeBuilder extends TypeBuilder {
542
545
  Deref<T extends TRef>(schema: T): TDeref<T>;
543
546
  /** `[Standard]` Creates a Enum type */
544
547
  Enum<T extends Record<string, string | number>>(item: T, options?: SchemaOptions): TEnum<T>;
545
- /** `[Standard]` A conditional type expression that will return the true type if the left extends the right */
548
+ /** `[Standard]` A conditional type expression that will return the true type if the left type extends the right */
546
549
  Extends<L extends TSchema, R extends TSchema, T extends TSchema, U extends TSchema>(left: L, right: R, trueType: T, falseType: U, options?: SchemaOptions): TExtends<L, R, T, U>;
547
- /** `[Standard]` Excludes from left any type that is not assignable to the right. */
550
+ /** `[Standard]` Excludes from the left type any type that is not assignable to the right */
548
551
  Exclude<L extends TSchema, R extends TSchema>(left: L, right: R, options?: SchemaOptions): TExclude<L, R>;
549
- /** `[Standard]` Extracts from left any type that is assignable to the right. */
552
+ /** `[Standard]` Extracts from left left any type that is assignable to the right */
550
553
  Extract<L extends TSchema, R extends TSchema>(left: L, right: R, options?: SchemaOptions): TExtract<L, R>;
551
554
  /** `[Standard]` Creates an Integer type */
552
555
  Integer(options?: NumericOptions<number>): TInteger;
@@ -567,7 +570,7 @@ export declare class StandardTypeBuilder extends TypeBuilder {
567
570
  Null(options?: SchemaOptions): TNull;
568
571
  /** `[Standard]` Creates a Number type */
569
572
  Number(options?: NumericOptions<number>): TNumber;
570
- /** `[Standard]` Creates a Object type */
573
+ /** `[Standard]` Creates an Object type */
571
574
  Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T>;
572
575
  /** `[Standard]` Creates a mapped type whose keys are omitted from the given type */
573
576
  Omit<T extends TSchema, K extends (keyof Static<T>)[]>(schema: T, keys: readonly [...K], options?: SchemaOptions): TOmit<T, K[number]>;
@@ -607,7 +610,7 @@ export declare class StandardTypeBuilder extends TypeBuilder {
607
610
  Unsafe<T>(options?: UnsafeOptions): TUnsafe<T>;
608
611
  }
609
612
  export declare class ExtendedTypeBuilder extends StandardTypeBuilder {
610
- /** `[Extended]` Creates a BigInt */
613
+ /** `[Extended]` Creates a BigInt type */
611
614
  BigInt(options?: NumericOptions<bigint>): TBigInt;
612
615
  /** `[Extended]` Extracts the ConstructorParameters from the given Constructor type */
613
616
  ConstructorParameters<T extends TConstructor<any[], any>>(schema: T, options?: SchemaOptions): TConstructorParameters<T>;
package/typebox.js CHANGED
@@ -27,13 +27,14 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.Type = exports.StandardType = exports.ExtendedTypeBuilder = exports.StandardTypeBuilder = exports.TypeBuilder = exports.KeyResolver = exports.ObjectMap = exports.TypeClone = exports.TypeExtends = exports.TypeExtendsResult = exports.ExtendsUndefined = exports.TypeGuard = exports.TypeGuardUnknownTypeError = exports.FormatRegistry = exports.ReferenceRegistry = exports.TypeRegistry = exports.Modifier = exports.Hint = exports.Kind = void 0;
30
+ exports.Type = exports.StandardType = exports.ExtendedTypeBuilder = exports.StandardTypeBuilder = exports.TypeBuilder = exports.KeyResolver = exports.ObjectMap = exports.TypeClone = exports.TypeExtends = exports.TypeExtendsResult = exports.ExtendsUndefined = exports.TypeGuard = exports.TypeGuardUnknownTypeError = exports.FormatRegistry = exports.ReferenceRegistry = exports.TypeRegistry = exports.Recursive = exports.Modifier = exports.Hint = exports.Kind = void 0;
31
31
  // -------------------------------------------------------------------------------------
32
- // Symbols
32
+ // Compositing Symbols
33
33
  // -------------------------------------------------------------------------------------
34
34
  exports.Kind = Symbol.for('TypeBox.Kind');
35
35
  exports.Hint = Symbol.for('TypeBox.Hint');
36
36
  exports.Modifier = Symbol.for('TypeBox.Modifier');
37
+ exports.Recursive = Symbol.for('TypeBox.Recursive');
37
38
  var TypeRegistry;
38
39
  (function (TypeRegistry) {
39
40
  const types = new Map();
@@ -85,7 +86,7 @@ var ReferenceRegistry;
85
86
  function DerefOne(schema) {
86
87
  if (TypeGuard.TRef(schema) || TypeGuard.TSelf(schema)) {
87
88
  if (!references.has(schema.$ref))
88
- throw Error(`ReferenceRegistry: Cannot deref schema with $id '${schema.$ref}`);
89
+ throw Error(`ReferenceRegistry: Cannot deref schema with $id '${schema.$ref}'`);
89
90
  return references.get(schema.$ref);
90
91
  }
91
92
  else {
@@ -1356,7 +1357,7 @@ var TypeExtends;
1356
1357
  return Unknown(left_, right_);
1357
1358
  if (TypeGuard.TVoid(left_))
1358
1359
  return Void(left_, right_);
1359
- throw Error(`TypeExtends: Unknown left operand '${left[exports.Kind]}'`);
1360
+ throw Error(`TypeExtends: Unknown left type operand '${left[exports.Kind]}'`);
1360
1361
  }
1361
1362
  function Extends(left, right) {
1362
1363
  return Visit(left, right);
@@ -1366,9 +1367,12 @@ var TypeExtends;
1366
1367
  // -------------------------------------------------------------------------------------
1367
1368
  // TypeClone
1368
1369
  // -------------------------------------------------------------------------------------
1369
- /** Specialized Clone for Types. */
1370
+ /** Specialized Clone for Types. Clones and removes non self-referential identifiers */
1370
1371
  var TypeClone;
1371
1372
  (function (TypeClone) {
1373
+ function IsRecursive(value) {
1374
+ return typeof value[exports.Recursive] === 'string';
1375
+ }
1372
1376
  function IsObject(value) {
1373
1377
  return typeof value === 'object' && value !== null && !globalThis.Array.isArray(value);
1374
1378
  }
@@ -1383,14 +1387,16 @@ var TypeClone;
1383
1387
  return clone;
1384
1388
  }
1385
1389
  function Visit(value) {
1386
- if (IsObject(value))
1387
- delete value['$id'];
1388
- if (IsObject(value))
1389
- return Object({ ...value });
1390
- if (IsArray(value))
1391
- return Array([...value]);
1392
- return value;
1390
+ const clone = IsObject(value) ? { ...value } : IsArray(value) ? [...value] : value;
1391
+ if (IsObject(clone) && !IsRecursive(clone))
1392
+ delete clone['$id'];
1393
+ if (IsObject(clone))
1394
+ return Object(clone);
1395
+ if (IsArray(clone))
1396
+ return Array(clone);
1397
+ return clone;
1393
1398
  }
1399
+ /** Clones a type. This function will omit non-self referential identifiers on the cloned type. */
1394
1400
  function Clone(schema, options) {
1395
1401
  return { ...Visit({ ...schema }), ...options };
1396
1402
  }
@@ -1503,7 +1509,7 @@ class StandardTypeBuilder extends TypeBuilder {
1503
1509
  }
1504
1510
  /** `[Standard]` Creates an Array type */
1505
1511
  Array(items, options = {}) {
1506
- return this.Create({ ...options, [exports.Kind]: 'Array', type: 'array', items });
1512
+ return this.Create({ ...options, [exports.Kind]: 'Array', type: 'array', items: TypeClone.Clone(items, {}) });
1507
1513
  }
1508
1514
  /** `[Standard]` Creates a Boolean type */
1509
1515
  Boolean(options = {}) {
@@ -1521,7 +1527,7 @@ class StandardTypeBuilder extends TypeBuilder {
1521
1527
  const properties = {};
1522
1528
  for (const object of schemas) {
1523
1529
  for (const [key, property] of globalThis.Object.entries(object.properties)) {
1524
- const mapped = key in properties ? this.Union([properties[key], property]) : property;
1530
+ const mapped = key in properties ? this.Union([properties[key], property]) : TypeClone.Clone(property, {});
1525
1531
  properties[key] = optional.has(key) ? this.Optional(mapped) : mapped;
1526
1532
  }
1527
1533
  }
@@ -1538,7 +1544,7 @@ class StandardTypeBuilder extends TypeBuilder {
1538
1544
  const anyOf = values.map((value) => (typeof value === 'string' ? { [exports.Kind]: 'Literal', type: 'string', const: value } : { [exports.Kind]: 'Literal', type: 'number', const: value }));
1539
1545
  return this.Create({ ...options, [exports.Kind]: 'Union', anyOf });
1540
1546
  }
1541
- /** `[Standard]` A conditional type expression that will return the true type if the left extends the right */
1547
+ /** `[Standard]` A conditional type expression that will return the true type if the left type extends the right */
1542
1548
  Extends(left, right, trueType, falseType, options = {}) {
1543
1549
  switch (TypeExtends.Extends(ReferenceRegistry.Deref(left), ReferenceRegistry.Deref(right))) {
1544
1550
  case TypeExtendsResult.Union:
@@ -1549,7 +1555,7 @@ class StandardTypeBuilder extends TypeBuilder {
1549
1555
  return TypeClone.Clone(falseType, options);
1550
1556
  }
1551
1557
  }
1552
- /** `[Standard]` Excludes from left any type that is not assignable to the right. */
1558
+ /** `[Standard]` Excludes from the left type any type that is not assignable to the right */
1553
1559
  Exclude(left, right, options = {}) {
1554
1560
  if (TypeGuard.TUnion(left)) {
1555
1561
  const narrowed = left.anyOf.filter((inner) => TypeExtends.Extends(inner, right) === TypeExtendsResult.False);
@@ -1559,7 +1565,7 @@ class StandardTypeBuilder extends TypeBuilder {
1559
1565
  return (TypeExtends.Extends(left, right) !== TypeExtendsResult.False ? this.Never(options) : TypeClone.Clone(left, options));
1560
1566
  }
1561
1567
  }
1562
- /** `[Standard]` Extracts from left any type that is assignable to the right. */
1568
+ /** `[Standard]` Extracts from left left any type that is assignable to the right */
1563
1569
  Extract(left, right, options = {}) {
1564
1570
  if (TypeGuard.TUnion(left)) {
1565
1571
  const narrowed = left.anyOf.filter((inner) => TypeExtends.Extends(inner, right) !== TypeExtendsResult.False);
@@ -1608,7 +1614,7 @@ class StandardTypeBuilder extends TypeBuilder {
1608
1614
  }
1609
1615
  /** `[Standard]` Creates a Not type. The first argument is the disallowed type, the second is the allowed. */
1610
1616
  Not(not, schema, options) {
1611
- return this.Create({ ...options, [exports.Kind]: 'Not', allOf: [{ not }, schema] });
1617
+ return this.Create({ ...options, [exports.Kind]: 'Not', allOf: [{ not: TypeClone.Clone(not, {}) }, TypeClone.Clone(schema, {})] });
1612
1618
  }
1613
1619
  /** `[Standard]` Creates a Null type */
1614
1620
  Null(options = {}) {
@@ -1618,16 +1624,19 @@ class StandardTypeBuilder extends TypeBuilder {
1618
1624
  Number(options = {}) {
1619
1625
  return this.Create({ ...options, [exports.Kind]: 'Number', type: 'number' });
1620
1626
  }
1621
- /** `[Standard]` Creates a Object type */
1627
+ /** `[Standard]` Creates an Object type */
1622
1628
  Object(properties, options = {}) {
1623
1629
  const keys = globalThis.Object.keys(properties);
1624
1630
  const optional = keys.filter((key) => TypeGuard.TOptional(properties[key]) || TypeGuard.TReadonlyOptional(properties[key]));
1625
1631
  const required = keys.filter((name) => !optional.includes(name));
1632
+ const clonedProperties = globalThis.Object.getOwnPropertyNames(properties).reduce((acc, key) => {
1633
+ return { ...acc, [key]: TypeClone.Clone(properties[key], {}) };
1634
+ }, {});
1626
1635
  if (required.length > 0) {
1627
- return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties: TypeClone.Clone(properties, {}), required });
1636
+ return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties, required });
1628
1637
  }
1629
1638
  else {
1630
- return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties: TypeClone.Clone(properties, {}) });
1639
+ return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties });
1631
1640
  }
1632
1641
  }
1633
1642
  Omit(schema, unresolved, options = {}) {
@@ -1691,7 +1700,7 @@ class StandardTypeBuilder extends TypeBuilder {
1691
1700
  Record(key, schema, options = {}) {
1692
1701
  if (TypeGuard.TLiteral(key)) {
1693
1702
  if (typeof key.const === 'string' || typeof key.const === 'number') {
1694
- return this.Object({ [key.const]: schema }, options);
1703
+ return this.Object({ [key.const]: TypeClone.Clone(schema, {}) }, options);
1695
1704
  }
1696
1705
  else
1697
1706
  throw Error('TypeBuilder: Record key can only be derived from literals of number or string');
@@ -1709,7 +1718,7 @@ class StandardTypeBuilder extends TypeBuilder {
1709
1718
  ...options,
1710
1719
  [exports.Kind]: 'Record',
1711
1720
  type: 'object',
1712
- patternProperties: { [pattern]: schema },
1721
+ patternProperties: { [pattern]: TypeClone.Clone(schema, {}) },
1713
1722
  additionalProperties: false,
1714
1723
  });
1715
1724
  }
@@ -1720,12 +1729,12 @@ class StandardTypeBuilder extends TypeBuilder {
1720
1729
  const self = callback({ [exports.Kind]: 'Self', $ref: `${options.$id}` });
1721
1730
  const reassign = self;
1722
1731
  reassign.$id = options.$id; // required as $id is readonly
1723
- return this.Create({ ...options, ...self });
1732
+ return this.Create({ ...options, ...self, [exports.Recursive]: reassign.$id });
1724
1733
  }
1725
1734
  /** `[Standard]` Creates a Ref type. The referenced type must contain a $id */
1726
1735
  Ref(schema, options = {}) {
1727
1736
  if (schema.$id === undefined)
1728
- throw Error('TypeBuilder.Ref: Referenced schema must specify an $id');
1737
+ throw Error('StandardTypeBuilder.Ref: Target type must specify an $id');
1729
1738
  return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: schema.$id });
1730
1739
  }
1731
1740
  /** `[Standard]` Creates a mapped type where all properties are Required */
@@ -1761,9 +1770,10 @@ class StandardTypeBuilder extends TypeBuilder {
1761
1770
  /** `[Standard]` Creates a Tuple type */
1762
1771
  Tuple(items, options = {}) {
1763
1772
  const [additionalItems, minItems, maxItems] = [false, items.length, items.length];
1773
+ const clonedItems = items.map((item) => TypeClone.Clone(item, {}));
1764
1774
  // prettier-ignore
1765
1775
  const schema = (items.length > 0 ?
1766
- { ...options, [exports.Kind]: 'Tuple', type: 'array', items, additionalItems, minItems, maxItems } :
1776
+ { ...options, [exports.Kind]: 'Tuple', type: 'array', items: clonedItems, additionalItems, minItems, maxItems } :
1767
1777
  { ...options, [exports.Kind]: 'Tuple', type: 'array', minItems, maxItems });
1768
1778
  return this.Create(schema);
1769
1779
  }
@@ -1772,8 +1782,8 @@ class StandardTypeBuilder extends TypeBuilder {
1772
1782
  return this.Never(options);
1773
1783
  if (anyOf.length === 1)
1774
1784
  return TypeClone.Clone(anyOf[0], options);
1775
- const cloned = anyOf.map((schema) => TypeClone.Clone(schema, {}));
1776
- return this.Create({ ...options, [exports.Kind]: 'Union', anyOf: cloned });
1785
+ const clonedAnyOf = anyOf.map((schema) => TypeClone.Clone(schema, {}));
1786
+ return this.Create({ ...options, [exports.Kind]: 'Union', anyOf: clonedAnyOf });
1777
1787
  }
1778
1788
  /** `[Standard]` Creates an Unknown type */
1779
1789
  Unknown(options = {}) {
@@ -1789,7 +1799,7 @@ exports.StandardTypeBuilder = StandardTypeBuilder;
1789
1799
  // TypeBuilder
1790
1800
  // -------------------------------------------------------------------------------------
1791
1801
  class ExtendedTypeBuilder extends StandardTypeBuilder {
1792
- /** `[Extended]` Creates a BigInt */
1802
+ /** `[Extended]` Creates a BigInt type */
1793
1803
  BigInt(options = {}) {
1794
1804
  return this.Create({ ...options, [exports.Kind]: 'BigInt', type: 'null', typeOf: 'BigInt' });
1795
1805
  }
@@ -1798,15 +1808,17 @@ class ExtendedTypeBuilder extends StandardTypeBuilder {
1798
1808
  return this.Tuple([...schema.parameters], { ...options });
1799
1809
  }
1800
1810
  Constructor(parameters, returns, options = {}) {
1801
- if (parameters[exports.Kind] === 'Tuple') {
1802
- const inner = parameters.items === undefined ? [] : parameters.items;
1803
- return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters: inner, returns });
1811
+ const clonedReturns = TypeClone.Clone(returns, {});
1812
+ if (TypeGuard.TTuple(parameters)) {
1813
+ const clonedParameters = parameters.items === undefined ? [] : parameters.items.map((parameter) => TypeClone.Clone(parameter, {}));
1814
+ return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters: clonedParameters, returns: clonedReturns });
1804
1815
  }
1805
1816
  else if (globalThis.Array.isArray(parameters)) {
1806
- return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters, returns });
1817
+ const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter, {}));
1818
+ return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'object', instanceOf: 'Constructor', parameters: clonedParameters, returns: clonedReturns });
1807
1819
  }
1808
1820
  else {
1809
- throw new Error('TypeBuilder.Constructor: Invalid parameters');
1821
+ throw new Error('ExtendedTypeBuilder.Constructor: Invalid parameters');
1810
1822
  }
1811
1823
  }
1812
1824
  /** `[Extended]` Creates a Date type */
@@ -1814,15 +1826,17 @@ class ExtendedTypeBuilder extends StandardTypeBuilder {
1814
1826
  return this.Create({ ...options, [exports.Kind]: 'Date', type: 'object', instanceOf: 'Date' });
1815
1827
  }
1816
1828
  Function(parameters, returns, options = {}) {
1817
- if (parameters[exports.Kind] === 'Tuple') {
1818
- const inner = parameters.items === undefined ? [] : parameters.items;
1819
- return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters: inner, returns });
1829
+ const clonedReturns = TypeClone.Clone(returns, {});
1830
+ if (TypeGuard.TTuple(parameters)) {
1831
+ const clonedParameters = parameters.items === undefined ? [] : parameters.items.map((parameter) => TypeClone.Clone(parameter, {}));
1832
+ return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters: clonedParameters, returns: clonedReturns });
1820
1833
  }
1821
1834
  else if (globalThis.Array.isArray(parameters)) {
1822
- return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters, returns });
1835
+ const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter, {}));
1836
+ return this.Create({ ...options, [exports.Kind]: 'Function', type: 'object', instanceOf: 'Function', parameters: clonedParameters, returns: clonedReturns });
1823
1837
  }
1824
1838
  else {
1825
- throw new Error('TypeBuilder.Function: Invalid parameters');
1839
+ throw new Error('ExtendedTypeBuilder.Function: Invalid parameters');
1826
1840
  }
1827
1841
  }
1828
1842
  /** `[Extended]` Extracts the InstanceType from the given Constructor */
@@ -1835,7 +1849,7 @@ class ExtendedTypeBuilder extends StandardTypeBuilder {
1835
1849
  }
1836
1850
  /** `[Extended]` Creates a Promise type */
1837
1851
  Promise(item, options = {}) {
1838
- return this.Create({ ...options, [exports.Kind]: 'Promise', type: 'object', instanceOf: 'Promise', item });
1852
+ return this.Create({ ...options, [exports.Kind]: 'Promise', type: 'object', instanceOf: 'Promise', item: TypeClone.Clone(item, {}) });
1839
1853
  }
1840
1854
  /** `[Extended]` Creates a regular expression type */
1841
1855
  RegEx(regex, options = {}) {
package/value/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ValueError, ValueErrorType } from '../errors/index';
1
+ export { ValueError, ValueErrorIterator, ValueErrorType } from '../errors/index';
2
2
  export { ValueHash } from './hash';
3
3
  export { Edit, Insert, Update, Delete } from './delta';
4
4
  export * from './pointer';
package/value/index.js CHANGED
@@ -41,8 +41,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
41
41
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
42
42
  };
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.Delete = exports.Update = exports.Insert = exports.Edit = exports.ValueHash = exports.ValueErrorType = void 0;
44
+ exports.Delete = exports.Update = exports.Insert = exports.Edit = exports.ValueHash = exports.ValueErrorType = exports.ValueErrorIterator = void 0;
45
45
  var index_1 = require("../errors/index");
46
+ Object.defineProperty(exports, "ValueErrorIterator", { enumerable: true, get: function () { return index_1.ValueErrorIterator; } });
46
47
  Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } });
47
48
  var hash_1 = require("./hash");
48
49
  Object.defineProperty(exports, "ValueHash", { enumerable: true, get: function () { return hash_1.ValueHash; } });
package/value/value.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as Types from '../typebox';
2
- import { ValueError } from '../errors/index';
2
+ import { ValueErrorIterator } from '../errors/index';
3
3
  import { Edit } from './delta';
4
4
  /** Provides functions to perform structural updates to JavaScript values */
5
5
  export declare namespace Value {
@@ -14,7 +14,7 @@ export declare namespace Value {
14
14
  /** Returns a structural clone of the given value */
15
15
  function Clone<T>(value: T): T;
16
16
  /** Returns an iterator for each error in this value. */
17
- function Errors<T extends Types.TSchema>(schema: T, value: unknown): IterableIterator<ValueError>;
17
+ function Errors<T extends Types.TSchema>(schema: T, value: unknown): ValueErrorIterator;
18
18
  /** Returns true if left and right values are structurally equal */
19
19
  function Equal<T>(left: T, right: unknown): right is T;
20
20
  /** Returns edits to transform the current value into the next value */