@sinclair/typebox 0.24.38 → 0.24.41

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.
@@ -151,6 +151,9 @@ var TypeCompiler;
151
151
  yield `(${value} === '${schema.const}')`;
152
152
  }
153
153
  }
154
+ function* Never(schema, value) {
155
+ yield `(false)`;
156
+ }
154
157
  function* Null(schema, value) {
155
158
  yield `(${value} === null)`;
156
159
  }
@@ -299,6 +302,8 @@ var TypeCompiler;
299
302
  return yield* Integer(anySchema, value);
300
303
  case 'Literal':
301
304
  return yield* Literal(anySchema, value);
305
+ case 'Never':
306
+ return yield* Never(anySchema, value);
302
307
  case 'Null':
303
308
  return yield* Null(anySchema, value);
304
309
  case 'Number':
@@ -13,34 +13,35 @@ export declare enum ValueErrorType {
13
13
  IntegerMinimum = 10,
14
14
  IntegerMaximum = 11,
15
15
  Literal = 12,
16
- Null = 13,
17
- Number = 14,
18
- NumberMultipleOf = 15,
19
- NumberExclusiveMinimum = 16,
20
- NumberExclusiveMaximum = 17,
21
- NumberMinumum = 18,
22
- NumberMaximum = 19,
23
- Object = 20,
24
- ObjectMinProperties = 21,
25
- ObjectMaxProperties = 22,
26
- ObjectAdditionalProperties = 23,
27
- Promise = 24,
28
- RecordKeyNumeric = 25,
29
- RecordKeyString = 26,
30
- String = 27,
31
- StringMinLength = 28,
32
- StringMaxLength = 29,
33
- StringPattern = 30,
34
- StringFormatUnknown = 31,
35
- StringFormat = 32,
36
- TupleZeroLength = 33,
37
- TupleLength = 34,
38
- Undefined = 35,
39
- Union = 36,
40
- Uint8Array = 37,
41
- Uint8ArrayMinByteLength = 38,
42
- Uint8ArrayMaxByteLength = 39,
43
- Void = 40
16
+ Never = 13,
17
+ Null = 14,
18
+ Number = 15,
19
+ NumberMultipleOf = 16,
20
+ NumberExclusiveMinimum = 17,
21
+ NumberExclusiveMaximum = 18,
22
+ NumberMinumum = 19,
23
+ NumberMaximum = 20,
24
+ Object = 21,
25
+ ObjectMinProperties = 22,
26
+ ObjectMaxProperties = 23,
27
+ ObjectAdditionalProperties = 24,
28
+ Promise = 25,
29
+ RecordKeyNumeric = 26,
30
+ RecordKeyString = 27,
31
+ String = 28,
32
+ StringMinLength = 29,
33
+ StringMaxLength = 30,
34
+ StringPattern = 31,
35
+ StringFormatUnknown = 32,
36
+ StringFormat = 33,
37
+ TupleZeroLength = 34,
38
+ TupleLength = 35,
39
+ Undefined = 36,
40
+ Union = 37,
41
+ Uint8Array = 38,
42
+ Uint8ArrayMinByteLength = 39,
43
+ Uint8ArrayMaxByteLength = 40,
44
+ Void = 41
44
45
  }
45
46
  export interface ValueError {
46
47
  type: ValueErrorType;
package/errors/errors.js CHANGED
@@ -48,34 +48,35 @@ var ValueErrorType;
48
48
  ValueErrorType[ValueErrorType["IntegerMinimum"] = 10] = "IntegerMinimum";
49
49
  ValueErrorType[ValueErrorType["IntegerMaximum"] = 11] = "IntegerMaximum";
50
50
  ValueErrorType[ValueErrorType["Literal"] = 12] = "Literal";
51
- ValueErrorType[ValueErrorType["Null"] = 13] = "Null";
52
- ValueErrorType[ValueErrorType["Number"] = 14] = "Number";
53
- ValueErrorType[ValueErrorType["NumberMultipleOf"] = 15] = "NumberMultipleOf";
54
- ValueErrorType[ValueErrorType["NumberExclusiveMinimum"] = 16] = "NumberExclusiveMinimum";
55
- ValueErrorType[ValueErrorType["NumberExclusiveMaximum"] = 17] = "NumberExclusiveMaximum";
56
- ValueErrorType[ValueErrorType["NumberMinumum"] = 18] = "NumberMinumum";
57
- ValueErrorType[ValueErrorType["NumberMaximum"] = 19] = "NumberMaximum";
58
- ValueErrorType[ValueErrorType["Object"] = 20] = "Object";
59
- ValueErrorType[ValueErrorType["ObjectMinProperties"] = 21] = "ObjectMinProperties";
60
- ValueErrorType[ValueErrorType["ObjectMaxProperties"] = 22] = "ObjectMaxProperties";
61
- ValueErrorType[ValueErrorType["ObjectAdditionalProperties"] = 23] = "ObjectAdditionalProperties";
62
- ValueErrorType[ValueErrorType["Promise"] = 24] = "Promise";
63
- ValueErrorType[ValueErrorType["RecordKeyNumeric"] = 25] = "RecordKeyNumeric";
64
- ValueErrorType[ValueErrorType["RecordKeyString"] = 26] = "RecordKeyString";
65
- ValueErrorType[ValueErrorType["String"] = 27] = "String";
66
- ValueErrorType[ValueErrorType["StringMinLength"] = 28] = "StringMinLength";
67
- ValueErrorType[ValueErrorType["StringMaxLength"] = 29] = "StringMaxLength";
68
- ValueErrorType[ValueErrorType["StringPattern"] = 30] = "StringPattern";
69
- ValueErrorType[ValueErrorType["StringFormatUnknown"] = 31] = "StringFormatUnknown";
70
- ValueErrorType[ValueErrorType["StringFormat"] = 32] = "StringFormat";
71
- ValueErrorType[ValueErrorType["TupleZeroLength"] = 33] = "TupleZeroLength";
72
- ValueErrorType[ValueErrorType["TupleLength"] = 34] = "TupleLength";
73
- ValueErrorType[ValueErrorType["Undefined"] = 35] = "Undefined";
74
- ValueErrorType[ValueErrorType["Union"] = 36] = "Union";
75
- ValueErrorType[ValueErrorType["Uint8Array"] = 37] = "Uint8Array";
76
- ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 38] = "Uint8ArrayMinByteLength";
77
- ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 39] = "Uint8ArrayMaxByteLength";
78
- ValueErrorType[ValueErrorType["Void"] = 40] = "Void";
51
+ ValueErrorType[ValueErrorType["Never"] = 13] = "Never";
52
+ ValueErrorType[ValueErrorType["Null"] = 14] = "Null";
53
+ ValueErrorType[ValueErrorType["Number"] = 15] = "Number";
54
+ ValueErrorType[ValueErrorType["NumberMultipleOf"] = 16] = "NumberMultipleOf";
55
+ ValueErrorType[ValueErrorType["NumberExclusiveMinimum"] = 17] = "NumberExclusiveMinimum";
56
+ ValueErrorType[ValueErrorType["NumberExclusiveMaximum"] = 18] = "NumberExclusiveMaximum";
57
+ ValueErrorType[ValueErrorType["NumberMinumum"] = 19] = "NumberMinumum";
58
+ ValueErrorType[ValueErrorType["NumberMaximum"] = 20] = "NumberMaximum";
59
+ ValueErrorType[ValueErrorType["Object"] = 21] = "Object";
60
+ ValueErrorType[ValueErrorType["ObjectMinProperties"] = 22] = "ObjectMinProperties";
61
+ ValueErrorType[ValueErrorType["ObjectMaxProperties"] = 23] = "ObjectMaxProperties";
62
+ ValueErrorType[ValueErrorType["ObjectAdditionalProperties"] = 24] = "ObjectAdditionalProperties";
63
+ ValueErrorType[ValueErrorType["Promise"] = 25] = "Promise";
64
+ ValueErrorType[ValueErrorType["RecordKeyNumeric"] = 26] = "RecordKeyNumeric";
65
+ ValueErrorType[ValueErrorType["RecordKeyString"] = 27] = "RecordKeyString";
66
+ ValueErrorType[ValueErrorType["String"] = 28] = "String";
67
+ ValueErrorType[ValueErrorType["StringMinLength"] = 29] = "StringMinLength";
68
+ ValueErrorType[ValueErrorType["StringMaxLength"] = 30] = "StringMaxLength";
69
+ ValueErrorType[ValueErrorType["StringPattern"] = 31] = "StringPattern";
70
+ ValueErrorType[ValueErrorType["StringFormatUnknown"] = 32] = "StringFormatUnknown";
71
+ ValueErrorType[ValueErrorType["StringFormat"] = 33] = "StringFormat";
72
+ ValueErrorType[ValueErrorType["TupleZeroLength"] = 34] = "TupleZeroLength";
73
+ ValueErrorType[ValueErrorType["TupleLength"] = 35] = "TupleLength";
74
+ ValueErrorType[ValueErrorType["Undefined"] = 36] = "Undefined";
75
+ ValueErrorType[ValueErrorType["Union"] = 37] = "Union";
76
+ ValueErrorType[ValueErrorType["Uint8Array"] = 38] = "Uint8Array";
77
+ ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 39] = "Uint8ArrayMinByteLength";
78
+ ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 40] = "Uint8ArrayMaxByteLength";
79
+ ValueErrorType[ValueErrorType["Void"] = 41] = "Void";
79
80
  })(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
80
81
  // -------------------------------------------------------------------
81
82
  // ValueErrors
@@ -149,6 +150,9 @@ var ValueErrors;
149
150
  return yield { type: ValueErrorType.Literal, schema, path, value, message: `Expected ${error}` };
150
151
  }
151
152
  }
153
+ function* Never(schema, references, path, value) {
154
+ yield { type: ValueErrorType.Never, schema, path, value, message: `Value cannot be validated` };
155
+ }
152
156
  function* Null(schema, references, path, value) {
153
157
  if (!(value === null)) {
154
158
  return yield { type: ValueErrorType.Null, schema, path, value, message: `Expected null` };
@@ -337,6 +341,8 @@ var ValueErrors;
337
341
  return yield* Integer(anySchema, anyReferences, path, value);
338
342
  case 'Literal':
339
343
  return yield* Literal(anySchema, anyReferences, path, value);
344
+ case 'Never':
345
+ return yield* Never(anySchema, anyReferences, path, value);
340
346
  case 'Null':
341
347
  return yield* Null(anySchema, anyReferences, path, value);
342
348
  case 'Number':
package/guard/guard.d.ts CHANGED
@@ -19,6 +19,8 @@ export declare namespace TypeGuard {
19
19
  function TInteger(schema: unknown): schema is Types.TInteger;
20
20
  /** Returns true if the given schema is TLiteral */
21
21
  function TLiteral(schema: unknown): schema is Types.TLiteral;
22
+ /** Returns true if the given schema is TNever */
23
+ function TNever(schema: unknown): schema is Types.TNever;
22
24
  /** Returns true if the given schema is TNull */
23
25
  function TNull(schema: unknown): schema is Types.TNull;
24
26
  /** Returns true if the given schema is TNumber */
package/guard/guard.js CHANGED
@@ -153,6 +153,22 @@ var TypeGuard;
153
153
  return IsObject(schema) && schema[Types.Kind] === 'Literal' && IsOptionalString(schema.$id) && (IsString(schema.const) || IsNumber(schema.const) || IsBoolean(schema.const));
154
154
  }
155
155
  TypeGuard.TLiteral = TLiteral;
156
+ /** Returns true if the given schema is TNever */
157
+ function TNever(schema) {
158
+ return (IsObject(schema) &&
159
+ schema[Types.Kind] === 'Never' &&
160
+ IsArray(schema.allOf) &&
161
+ schema.allOf.length === 2 &&
162
+ IsObject(schema.allOf[0]) &&
163
+ IsString(schema.allOf[0].type) &&
164
+ schema.allOf[0].type === 'number' &&
165
+ schema.allOf[0].const === 0 &&
166
+ IsObject(schema.allOf[1]) &&
167
+ IsString(schema.allOf[1].type) &&
168
+ schema.allOf[1].type === 'number' &&
169
+ schema.allOf[1].const === 1);
170
+ }
171
+ TypeGuard.TNever = TNever;
156
172
  /** Returns true if the given schema is TNull */
157
173
  function TNull(schema) {
158
174
  return IsObject(schema) && schema[Types.Kind] === 'Null' && schema.type === 'null' && IsOptionalString(schema.$id);
@@ -302,6 +318,7 @@ var TypeGuard;
302
318
  TFunction(schema) ||
303
319
  TInteger(schema) ||
304
320
  TLiteral(schema) ||
321
+ TNever(schema) ||
305
322
  TNull(schema) ||
306
323
  TNumber(schema) ||
307
324
  TObject(schema) ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.38",
3
+ "version": "0.24.41",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -302,6 +302,17 @@ The following table lists the standard TypeBox types.
302
302
  │ │ │ } │
303
303
  │ │ │ │
304
304
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
305
+ │ const T = Type.Never() │ type T = never │ const T = { │
306
+ │ │ │ allOf: [{ │
307
+ │ │ │ type: 'number' │
308
+ │ │ │ const: 0 │
309
+ │ │ │ }, { │
310
+ │ │ │ type: 'number' │
311
+ │ │ │ const: 1 │
312
+ │ │ │ }] │
313
+ │ │ │ } │
314
+ │ │ │ │
315
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
305
316
  │ const T = Type.Record( │ type T = Record< │ const T = { │
306
317
  │ Type.String(), │ string, │ type: 'object', │
307
318
  │ Type.Number() │ number, │ patternProperties: { │
@@ -428,7 +439,7 @@ const T = Type.Array(Type.Integer(), { minItems: 5 })
428
439
 
429
440
  ### Extended
430
441
 
431
- In addition to JSON schema types, TypeBox provides several extended types that allow for `function` and `constructor` types to be composed. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.
442
+ In addition to JSON schema types, TypeBox provides several extended types that allow for the composition of `function` and `constructor` types. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.
432
443
 
433
444
  ```typescript
434
445
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
package/typebox.d.ts CHANGED
@@ -116,15 +116,26 @@ export declare type UnionToTuple<U, L = UnionLast<U>> = [U] extends [never] ? []
116
116
  export declare type UnionStringLiteralToTuple<T> = T extends TUnion<infer L> ? {
117
117
  [I in keyof L]: L[I] extends TLiteral<infer C> ? C : never;
118
118
  } : never;
119
- export declare type TKeyOf<T extends TObject> = {
119
+ export declare type UnionLiteralsFromObject<T extends TObject> = {
120
120
  [K in ObjectPropertyKeys<T>]: TLiteral<K>;
121
121
  } extends infer R ? UnionToTuple<R[keyof R]> : never;
122
+ export interface TKeyOf<T extends TObject> extends TUnion<UnionLiteralsFromObject<T>> {
123
+ }
122
124
  export declare type TLiteralValue = string | number | boolean;
123
125
  export interface TLiteral<T extends TLiteralValue = TLiteralValue> extends TSchema {
124
126
  [Kind]: 'Literal';
125
127
  static: T;
126
128
  const: T;
127
129
  }
130
+ export interface TNever extends TSchema {
131
+ [Kind]: 'Never';
132
+ static: never;
133
+ allOf: [{
134
+ const: 0;
135
+ }, {
136
+ const: 1;
137
+ }];
138
+ }
128
139
  export interface TNull extends TSchema {
129
140
  [Kind]: 'Null';
130
141
  static: null;
@@ -320,9 +331,11 @@ export declare class TypeBuilder {
320
331
  /** Creates a intersect type. */
321
332
  Intersect<T extends TObject[]>(objects: [...T], options?: ObjectOptions): TIntersect<T>;
322
333
  /** Creates a keyof type */
323
- KeyOf<T extends TObject>(object: T, options?: SchemaOptions): TUnion<TKeyOf<T>>;
334
+ KeyOf<T extends TObject>(object: T, options?: SchemaOptions): TKeyOf<T>;
324
335
  /** Creates a literal type. */
325
336
  Literal<T extends TLiteralValue>(value: T, options?: SchemaOptions): TLiteral<T>;
337
+ /** Creates a never type */
338
+ Never(options?: SchemaOptions): TNever;
326
339
  /** Creates a null type */
327
340
  Null(options?: SchemaOptions): TNull;
328
341
  /** Creates a number type */
@@ -366,6 +379,7 @@ export declare class TypeBuilder {
366
379
  /** Creates a undefined type */
367
380
  Undefined(options?: SchemaOptions): TUndefined;
368
381
  /** Creates a union type */
382
+ Union(items: [], options?: SchemaOptions): TNever;
369
383
  Union<T extends TSchema[]>(items: [...T], options?: SchemaOptions): TUnion<T>;
370
384
  /** Creates a Uint8Array type */
371
385
  Uint8Array(options?: Uint8ArrayOptions): TUint8Array;
package/typebox.js CHANGED
@@ -153,6 +153,17 @@ class TypeBuilder {
153
153
  Literal(value, options = {}) {
154
154
  return this.Create({ ...options, [exports.Kind]: 'Literal', const: value, type: typeof value });
155
155
  }
156
+ /** Creates a never type */
157
+ Never(options = {}) {
158
+ return this.Create({
159
+ ...options,
160
+ [exports.Kind]: 'Never',
161
+ allOf: [
162
+ { type: 'number', const: 0 },
163
+ { type: 'number', const: 1 },
164
+ ],
165
+ });
166
+ }
156
167
  /** Creates a null type */
157
168
  Null(options = {}) {
158
169
  return this.Create({ ...options, [exports.Kind]: 'Null', type: 'null' });
@@ -315,9 +326,8 @@ class TypeBuilder {
315
326
  Undefined(options = {}) {
316
327
  return this.Create({ ...options, [exports.Kind]: 'Undefined', type: 'object', specialized: 'Undefined' });
317
328
  }
318
- /** Creates a union type */
319
329
  Union(items, options = {}) {
320
- return this.Create({ ...options, [exports.Kind]: 'Union', anyOf: items });
330
+ return items.length === 0 ? exports.Type.Never({ ...options }) : this.Create({ ...options, [exports.Kind]: 'Union', anyOf: items });
321
331
  }
322
332
  /** Creates a Uint8Array type */
323
333
  Uint8Array(options = {}) {
package/value/cast.d.ts CHANGED
@@ -1,4 +1,21 @@
1
1
  import * as Types from '../typebox';
2
+ export declare class ValueCastReferenceTypeError extends Error {
3
+ readonly schema: Types.TRef | Types.TSelf;
4
+ constructor(schema: Types.TRef | Types.TSelf);
5
+ }
6
+ export declare class ValueCastArrayUniqueItemsTypeError extends Error {
7
+ readonly schema: Types.TSchema;
8
+ readonly value: unknown;
9
+ constructor(schema: Types.TSchema, value: unknown);
10
+ }
11
+ export declare class ValueCastNeverTypeError extends Error {
12
+ readonly schema: Types.TSchema;
13
+ constructor(schema: Types.TSchema);
14
+ }
15
+ export declare class ValueCastRecursiveTypeError extends Error {
16
+ readonly schema: Types.TSchema;
17
+ constructor(schema: Types.TSchema);
18
+ }
2
19
  export declare class ValueCastUnknownTypeError extends Error {
3
20
  readonly schema: Types.TSchema;
4
21
  constructor(schema: Types.TSchema);
package/value/cast.js CHANGED
@@ -27,50 +27,84 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ValueCast = exports.ValueCastUnknownTypeError = void 0;
30
+ exports.ValueCast = exports.ValueCastUnknownTypeError = exports.ValueCastRecursiveTypeError = exports.ValueCastNeverTypeError = exports.ValueCastArrayUniqueItemsTypeError = exports.ValueCastReferenceTypeError = void 0;
31
31
  const Types = require("../typebox");
32
32
  const create_1 = require("./create");
33
33
  const check_1 = require("./check");
34
- // --------------------------------------------------------------------------
35
- // Specialized Union Cast. Because a union can be one of many varying types
36
- // with properties potentially overlapping, we need a strategy to determine
37
- // which of those types we should cast into. This strategy needs to factor
38
- // the value provided by the user to make this decision.
39
- //
40
- // The following will score each union type found within the types anyOf
41
- // array. Typically this is executed for objects only, so the score is a
42
- // essentially a tally of how many properties are valid. The reasoning
43
- // here is the discriminator field would tip the scales in favor of that
44
- // union if other properties overlap and match.
45
- // --------------------------------------------------------------------------
34
+ const clone_1 = require("./clone");
46
35
  var UnionValueCast;
47
36
  (function (UnionValueCast) {
37
+ // ----------------------------------------------------------------------------------------------
38
+ // The following will score a schema against a value. For objects, the score is the tally of
39
+ // points awarded for each property of the value. Property points are (1.0 / propertyCount)
40
+ // to prevent large property counts biasing results. Properties that match literal values are
41
+ // maximally awarded as literals are typically used as union discriminator fields.
42
+ // ----------------------------------------------------------------------------------------------
48
43
  function Score(schema, references, value) {
49
- let score = 0;
50
44
  if (schema[Types.Kind] === 'Object' && typeof value === 'object' && value !== null) {
51
- const objectSchema = schema;
52
- const entries = globalThis.Object.entries(objectSchema.properties);
53
- score += entries.reduce((acc, [key, schema]) => acc + (check_1.ValueCheck.Check(schema, references, value[key]) ? 1 : 0), 0);
45
+ const object = schema;
46
+ const keys = Object.keys(value);
47
+ const entries = globalThis.Object.entries(object.properties);
48
+ const [point, max] = [1 / entries.length, entries.length];
49
+ return entries.reduce((acc, [key, schema]) => {
50
+ const literal = schema[Types.Kind] === 'Literal' && schema.const === value[key] ? max : 0;
51
+ const checks = check_1.ValueCheck.Check(schema, references, value[key]) ? point : 0;
52
+ const exists = keys.includes(key) ? point : 0;
53
+ return acc + (literal + checks + exists);
54
+ }, 0);
55
+ }
56
+ else {
57
+ return check_1.ValueCheck.Check(schema, references, value) ? 1 : 0;
54
58
  }
55
- return score;
56
59
  }
57
- function Select(schema, references, value) {
58
- let select = schema.anyOf[0];
59
- let best = 0;
60
- for (const subschema of schema.anyOf) {
61
- const score = Score(subschema, references, value);
60
+ function Select(union, references, value) {
61
+ let [select, best] = [union.anyOf[0], 0];
62
+ for (const schema of union.anyOf) {
63
+ const score = Score(schema, references, value);
62
64
  if (score > best) {
63
- select = subschema;
65
+ select = schema;
64
66
  best = score;
65
67
  }
66
68
  }
67
69
  return select;
68
70
  }
69
- function Create(schema, references, value) {
70
- return check_1.ValueCheck.Check(schema, references, value) ? value : ValueCast.Cast(Select(schema, references, value), references, value);
71
+ function Create(union, references, value) {
72
+ return check_1.ValueCheck.Check(union, references, value) ? clone_1.ValueClone.Clone(value) : ValueCast.Cast(Select(union, references, value), references, value);
71
73
  }
72
74
  UnionValueCast.Create = Create;
73
75
  })(UnionValueCast || (UnionValueCast = {}));
76
+ // -----------------------------------------------------------
77
+ // Errors
78
+ // -----------------------------------------------------------
79
+ class ValueCastReferenceTypeError extends Error {
80
+ constructor(schema) {
81
+ super(`ValueCast: Cannot locate referenced schema with $id '${schema.$ref}'`);
82
+ this.schema = schema;
83
+ }
84
+ }
85
+ exports.ValueCastReferenceTypeError = ValueCastReferenceTypeError;
86
+ class ValueCastArrayUniqueItemsTypeError extends Error {
87
+ constructor(schema, value) {
88
+ super('ValueCast: Array cast produced invalid data due to uniqueItems constraint');
89
+ this.schema = schema;
90
+ this.value = value;
91
+ }
92
+ }
93
+ exports.ValueCastArrayUniqueItemsTypeError = ValueCastArrayUniqueItemsTypeError;
94
+ class ValueCastNeverTypeError extends Error {
95
+ constructor(schema) {
96
+ super('ValueCast: Never types cannot be cast');
97
+ this.schema = schema;
98
+ }
99
+ }
100
+ exports.ValueCastNeverTypeError = ValueCastNeverTypeError;
101
+ class ValueCastRecursiveTypeError extends Error {
102
+ constructor(schema) {
103
+ super('ValueCast.Recursive: Cannot cast recursive schemas');
104
+ this.schema = schema;
105
+ }
106
+ }
107
+ exports.ValueCastRecursiveTypeError = ValueCastRecursiveTypeError;
74
108
  class ValueCastUnknownTypeError extends Error {
75
109
  constructor(schema) {
76
110
  super('ValueCast: Unknown type');
@@ -81,8 +115,11 @@ exports.ValueCastUnknownTypeError = ValueCastUnknownTypeError;
81
115
  var ValueCast;
82
116
  (function (ValueCast) {
83
117
  // -----------------------------------------------------------
84
- // Convert
118
+ // Guards
85
119
  // -----------------------------------------------------------
120
+ function IsArray(value) {
121
+ return typeof value === 'object' && globalThis.Array.isArray(value);
122
+ }
86
123
  function IsString(value) {
87
124
  return typeof value === 'string';
88
125
  }
@@ -107,6 +144,9 @@ var ValueCast;
107
144
  function IsValueFalse(value) {
108
145
  return value === false || (IsNumber(value) && value === 0) || (IsBigInt(value) && value === 0n) || (IsString(value) && (value.toLowerCase() === 'false' || value === '0'));
109
146
  }
147
+ // -----------------------------------------------------------
148
+ // Convert
149
+ // -----------------------------------------------------------
110
150
  function TryConvertString(value) {
111
151
  return IsValueToString(value) ? value.toString() : value;
112
152
  }
@@ -127,10 +167,17 @@ var ValueCast;
127
167
  }
128
168
  function Array(schema, references, value) {
129
169
  if (check_1.ValueCheck.Check(schema, references, value))
130
- return value;
131
- if (!globalThis.Array.isArray(value))
132
- return create_1.ValueCreate.Create(schema, references);
133
- return value.map((val) => Visit(schema.items, references, val));
170
+ return clone_1.ValueClone.Clone(value);
171
+ const created = IsArray(value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references);
172
+ const minimum = IsNumber(schema.minItems) && created.length < schema.minItems ? [...created, ...globalThis.Array.from({ length: schema.minItems - created.length }, () => null)] : created;
173
+ const maximum = IsNumber(schema.maxItems) && minimum.length > schema.maxItems ? minimum.slice(0, schema.maxItems) : minimum;
174
+ const casted = maximum.map((value) => Visit(schema.items, references, value));
175
+ if (schema.uniqueItems !== true)
176
+ return casted;
177
+ const unique = [...new Set(casted)];
178
+ if (!check_1.ValueCheck.Check(schema, references, unique))
179
+ throw new ValueCastArrayUniqueItemsTypeError(schema, unique);
180
+ return unique;
134
181
  }
135
182
  function Boolean(schema, references, value) {
136
183
  const conversion = TryConvertBoolean(value);
@@ -161,6 +208,9 @@ var ValueCast;
161
208
  function Literal(schema, references, value) {
162
209
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
163
210
  }
211
+ function Never(schema, references, value) {
212
+ throw new ValueCastNeverTypeError(schema);
213
+ }
164
214
  function Null(schema, references, value) {
165
215
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
166
216
  }
@@ -170,7 +220,7 @@ var ValueCast;
170
220
  }
171
221
  function Object(schema, references, value) {
172
222
  if (check_1.ValueCheck.Check(schema, references, value))
173
- return value;
223
+ return clone_1.ValueClone.Clone(value);
174
224
  if (value === null || typeof value !== 'object')
175
225
  return create_1.ValueCreate.Create(schema, references);
176
226
  const required = new Set(schema.required || []);
@@ -187,7 +237,7 @@ var ValueCast;
187
237
  }
188
238
  function Record(schema, references, value) {
189
239
  if (check_1.ValueCheck.Check(schema, references, value))
190
- return value;
240
+ return clone_1.ValueClone.Clone(value);
191
241
  if (value === null || typeof value !== 'object' || globalThis.Array.isArray(value))
192
242
  return create_1.ValueCreate.Create(schema, references);
193
243
  const subschemaKey = globalThis.Object.keys(schema.patternProperties)[0];
@@ -199,18 +249,18 @@ var ValueCast;
199
249
  return result;
200
250
  }
201
251
  function Recursive(schema, references, value) {
202
- throw new Error('ValueCast.Recursive: Cannot cast recursive schemas');
252
+ throw new ValueCastRecursiveTypeError(schema);
203
253
  }
204
254
  function Ref(schema, references, value) {
205
255
  const reference = references.find((reference) => reference.$id === schema.$ref);
206
256
  if (reference === undefined)
207
- throw new Error(`ValueCast.Ref: Cannot find schema with $id '${schema.$ref}'.`);
257
+ throw new ValueCastReferenceTypeError(schema);
208
258
  return Visit(reference, references, value);
209
259
  }
210
260
  function Self(schema, references, value) {
211
261
  const reference = references.find((reference) => reference.$id === schema.$ref);
212
262
  if (reference === undefined)
213
- throw new Error(`ValueCast.Self: Cannot find schema with $id '${schema.$ref}'.`);
263
+ throw new ValueCastReferenceTypeError(schema);
214
264
  return Visit(reference, references, value);
215
265
  }
216
266
  function String(schema, references, value) {
@@ -219,7 +269,7 @@ var ValueCast;
219
269
  }
220
270
  function Tuple(schema, references, value) {
221
271
  if (check_1.ValueCheck.Check(schema, references, value))
222
- return value;
272
+ return clone_1.ValueClone.Clone(value);
223
273
  if (!globalThis.Array.isArray(value))
224
274
  return create_1.ValueCreate.Create(schema, references);
225
275
  if (schema.items === undefined)
@@ -261,6 +311,8 @@ var ValueCast;
261
311
  return Integer(anySchema, anyReferences, value);
262
312
  case 'Literal':
263
313
  return Literal(anySchema, anyReferences, value);
314
+ case 'Never':
315
+ return Never(anySchema, anyReferences, value);
264
316
  case 'Null':
265
317
  return Null(anySchema, anyReferences, value);
266
318
  case 'Number':
package/value/check.js CHANGED
@@ -93,6 +93,9 @@ var ValueCheck;
93
93
  function Literal(schema, references, value) {
94
94
  return value === schema.const;
95
95
  }
96
+ function Never(schema, references, value) {
97
+ return false;
98
+ }
96
99
  function Null(schema, references, value) {
97
100
  return value === null;
98
101
  }
@@ -275,6 +278,8 @@ var ValueCheck;
275
278
  return Integer(anySchema, anyReferences, value);
276
279
  case 'Literal':
277
280
  return Literal(anySchema, anyReferences, value);
281
+ case 'Never':
282
+ return Never(anySchema, anyReferences, value);
278
283
  case 'Null':
279
284
  return Null(anySchema, anyReferences, value);
280
285
  case 'Number':
package/value/create.d.ts CHANGED
@@ -3,6 +3,10 @@ export declare class ValueCreateUnknownTypeError extends Error {
3
3
  readonly schema: Types.TSchema;
4
4
  constructor(schema: Types.TSchema);
5
5
  }
6
+ export declare class ValueCreateNeverTypeError extends Error {
7
+ readonly schema: Types.TSchema;
8
+ constructor(schema: Types.TSchema);
9
+ }
6
10
  export declare namespace ValueCreate {
7
11
  /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */
8
12
  function Visit<T extends Types.TSchema>(schema: T, references: Types.TSchema[]): Types.Static<T>;
package/value/create.js CHANGED
@@ -27,7 +27,7 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ValueCreate = exports.ValueCreateUnknownTypeError = void 0;
30
+ exports.ValueCreate = exports.ValueCreateNeverTypeError = exports.ValueCreateUnknownTypeError = void 0;
31
31
  const Types = require("../typebox");
32
32
  class ValueCreateUnknownTypeError extends Error {
33
33
  constructor(schema) {
@@ -36,6 +36,13 @@ class ValueCreateUnknownTypeError extends Error {
36
36
  }
37
37
  }
38
38
  exports.ValueCreateUnknownTypeError = ValueCreateUnknownTypeError;
39
+ class ValueCreateNeverTypeError extends Error {
40
+ constructor(schema) {
41
+ super('ValueCreate: Never types cannot be created');
42
+ this.schema = schema;
43
+ }
44
+ }
45
+ exports.ValueCreateNeverTypeError = ValueCreateNeverTypeError;
39
46
  var ValueCreate;
40
47
  (function (ValueCreate) {
41
48
  function Any(schema, references) {
@@ -125,6 +132,9 @@ var ValueCreate;
125
132
  function Literal(schema, references) {
126
133
  return schema.const;
127
134
  }
135
+ function Never(schema, references) {
136
+ throw new ValueCreateNeverTypeError(schema);
137
+ }
128
138
  function Null(schema, references) {
129
139
  return null;
130
140
  }
@@ -303,6 +313,8 @@ var ValueCreate;
303
313
  return Integer(anySchema, anyReferences);
304
314
  case 'Literal':
305
315
  return Literal(anySchema, anyReferences);
316
+ case 'Never':
317
+ return Never(anySchema, anyReferences);
306
318
  case 'Null':
307
319
  return Null(anySchema, anyReferences);
308
320
  case 'Number':
package/value/delta.js CHANGED
@@ -122,7 +122,6 @@ var ValueDelta;
122
122
  return yield* Value(path, current, next);
123
123
  }
124
124
  else {
125
- console.log('left', current);
126
125
  throw new Error('ValueDelta: Cannot produce edits for value');
127
126
  }
128
127
  }
package/value/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { ValueError, ValueErrorType } from '../errors/index';
2
+ export * from './pointer';
2
3
  export * from './value';
package/value/index.js CHANGED
@@ -44,4 +44,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
44
44
  exports.ValueErrorType = void 0;
45
45
  var index_1 = require("../errors/index");
46
46
  Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } });
47
+ __exportStar(require("./pointer"), exports);
47
48
  __exportStar(require("./value"), exports);
@@ -1,11 +1,22 @@
1
- /** RFC6901 JsonPointer */
1
+ export declare class ValuePointerRootSetError extends Error {
2
+ readonly value: unknown;
3
+ readonly path: string;
4
+ readonly update: unknown;
5
+ constructor(value: unknown, path: string, update: unknown);
6
+ }
7
+ export declare class ValuePointerRootDeleteError extends Error {
8
+ readonly value: unknown;
9
+ readonly path: string;
10
+ constructor(value: unknown, path: string);
11
+ }
12
+ /** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
2
13
  export declare namespace ValuePointer {
3
14
  /** Sets the value at the given pointer. If the value at the pointer does not exist it is created. */
4
- function Set(value: any, pointer: string, update: any): void;
5
- /** Deletes a value at the given pointer. */
6
- function Delete(value: any, pointer: string): any[] | undefined;
7
- /** True if a value exists at the given pointer */
8
- function Has(value: any, pointer: string): boolean;
9
- /** Gets the value at the given pointer */
10
- function Get(value: any, pointer: string): any;
15
+ function Set(value: unknown, path: string, update: unknown): void;
16
+ /** Deletes a value at the given path. */
17
+ function Delete(value: any, path: string): any[] | undefined;
18
+ /** True if a value exists at the given path */
19
+ function Has(value: any, path: string): boolean;
20
+ /** Gets the value at the given path */
21
+ function Get(value: any, path: string): any;
11
22
  }
package/value/pointer.js CHANGED
@@ -27,82 +27,122 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ValuePointer = void 0;
31
- /** RFC6901 JsonPointer */
30
+ exports.ValuePointer = exports.ValuePointerRootDeleteError = exports.ValuePointerRootSetError = void 0;
31
+ class ValuePointerRootSetError extends Error {
32
+ constructor(value, path, update) {
33
+ super('ValuePointer: Cannot set root value');
34
+ this.value = value;
35
+ this.path = path;
36
+ this.update = update;
37
+ }
38
+ }
39
+ exports.ValuePointerRootSetError = ValuePointerRootSetError;
40
+ class ValuePointerRootDeleteError extends Error {
41
+ constructor(value, path) {
42
+ super('ValuePointer: Cannot delete root value');
43
+ this.value = value;
44
+ this.path = path;
45
+ }
46
+ }
47
+ exports.ValuePointerRootDeleteError = ValuePointerRootDeleteError;
48
+ /** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
32
49
  var ValuePointer;
33
50
  (function (ValuePointer) {
34
- function Format(pointer) {
35
- if (pointer === '/')
36
- return [''];
37
- const split = pointer.split('/');
38
- const filter = split.filter((part) => part.length > 0);
39
- return filter.map((part) => part.replace(/~0/g, `~`).replace(/~1/g, `/`));
51
+ /** Formats the path into navigable components */
52
+ function* Format(path) {
53
+ function clear(chars) {
54
+ while (chars.length > 0)
55
+ chars.shift();
56
+ }
57
+ const chars = [];
58
+ for (let i = 0; i < path.length; i++) {
59
+ const char = path.charAt(i);
60
+ if (char === '/') {
61
+ if (i !== 0) {
62
+ yield chars.join('');
63
+ clear(chars);
64
+ }
65
+ }
66
+ else if (char === '~' && path.charAt(i + 1) === '0' && (path.charAt(i + 2) === '/' || i !== path.length - 1)) {
67
+ chars.push('~');
68
+ i += 1;
69
+ }
70
+ else if (char === '~' && path.charAt(i + 1) === '1' && (path.charAt(i + 2) === '/' || i !== path.length - 1)) {
71
+ chars.push('/');
72
+ i += 1;
73
+ }
74
+ else {
75
+ chars.push(char);
76
+ }
77
+ }
78
+ yield chars.join('');
79
+ clear(chars);
40
80
  }
41
81
  /** Sets the value at the given pointer. If the value at the pointer does not exist it is created. */
42
- function Set(value, pointer, update) {
43
- if (pointer === '')
44
- throw Error('Cannot set root value');
45
- const path = Format(pointer);
82
+ function Set(value, path, update) {
83
+ if (path === '')
84
+ throw new ValuePointerRootSetError(value, path, update);
85
+ const pointer = [...Format(path)];
46
86
  let current = value;
47
- while (path.length > 1) {
48
- const next = path.shift();
87
+ while (pointer.length > 1) {
88
+ const next = pointer.shift();
49
89
  if (current[next] === undefined)
50
90
  current[next] = {};
51
91
  current = current[next];
52
92
  }
53
- current[path.shift()] = update;
93
+ current[pointer.shift()] = update;
54
94
  }
55
95
  ValuePointer.Set = Set;
56
- /** Deletes a value at the given pointer. */
57
- function Delete(value, pointer) {
58
- if (pointer === '')
59
- throw Error('Cannot delete root value');
96
+ /** Deletes a value at the given path. */
97
+ function Delete(value, path) {
98
+ if (path === '')
99
+ throw new ValuePointerRootDeleteError(value, path);
60
100
  let current = value;
61
- const path = Format(pointer);
62
- while (path.length > 1) {
63
- const next = path.shift();
101
+ const pointer = [...Format(path)];
102
+ while (pointer.length > 1) {
103
+ const next = pointer.shift();
64
104
  if (current[next] === undefined)
65
105
  return;
66
106
  current = current[next];
67
107
  }
68
- if (Array.isArray(current)) {
69
- const index = parseInt(path.shift());
108
+ if (globalThis.Array.isArray(current)) {
109
+ const index = parseInt(pointer.shift());
70
110
  return current.splice(index, 1);
71
111
  }
72
112
  else {
73
- const key = path.shift();
113
+ const key = pointer.shift();
74
114
  delete current[key];
75
115
  }
76
116
  }
77
117
  ValuePointer.Delete = Delete;
78
- /** True if a value exists at the given pointer */
79
- function Has(value, pointer) {
80
- if (pointer === '')
118
+ /** True if a value exists at the given path */
119
+ function Has(value, path) {
120
+ if (path === '')
81
121
  return true;
82
122
  let current = value;
83
- const path = Format(pointer);
84
- while (path.length > 1) {
85
- const next = path.shift();
123
+ const pointer = [...Format(path)];
124
+ while (pointer.length > 1) {
125
+ const next = pointer.shift();
86
126
  if (current[next] === undefined)
87
127
  return false;
88
128
  current = current[next];
89
129
  }
90
- return current[path.shift()] !== undefined;
130
+ return current[pointer.shift()] !== undefined;
91
131
  }
92
132
  ValuePointer.Has = Has;
93
- /** Gets the value at the given pointer */
94
- function Get(value, pointer) {
95
- if (pointer === '')
133
+ /** Gets the value at the given path */
134
+ function Get(value, path) {
135
+ if (path === '')
96
136
  return value;
97
137
  let current = value;
98
- const path = Format(pointer);
99
- while (path.length > 1) {
100
- const next = path.shift();
138
+ const pointer = [...Format(path)];
139
+ while (pointer.length > 1) {
140
+ const next = pointer.shift();
101
141
  if (current[next] === undefined)
102
142
  return undefined;
103
143
  current = current[next];
104
144
  }
105
- return current[path.shift()];
145
+ return current[pointer.shift()];
106
146
  }
107
147
  ValuePointer.Get = Get;
108
148
  })(ValuePointer = exports.ValuePointer || (exports.ValuePointer = {}));
package/value/value.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as Types from '../typebox';
2
2
  import { ValueError } from '../errors/index';
3
3
  import { Edit } from './delta';
4
4
  export type { Edit } from './delta';
5
- /** The Value namespace provides type operations on values */
5
+ /** Value performs immutable operations on values */
6
6
  export declare namespace Value {
7
7
  /** Casts a value into a given type. The return value will retain as much information of the original value as possible. Cast will convert string, number and boolean values if a reasonable conversion is possible. */
8
8
  function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): Types.Static<T>;
package/value/value.js CHANGED
@@ -35,7 +35,7 @@ const clone_1 = require("./clone");
35
35
  const create_1 = require("./create");
36
36
  const check_1 = require("./check");
37
37
  const delta_1 = require("./delta");
38
- /** The Value namespace provides type operations on values */
38
+ /** Value performs immutable operations on values */
39
39
  var Value;
40
40
  (function (Value) {
41
41
  function Cast(...args) {