@sinclair/typebox 0.24.30 → 0.24.33

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.
@@ -31,14 +31,16 @@ export declare enum ValueErrorType {
31
31
  StringMinLength = 28,
32
32
  StringMaxLength = 29,
33
33
  StringPattern = 30,
34
- TupleZeroLength = 31,
35
- TupleLength = 32,
36
- Undefined = 33,
37
- Union = 34,
38
- Uint8Array = 35,
39
- Uint8ArrayMinByteLength = 36,
40
- Uint8ArrayMaxByteLength = 37,
41
- Void = 38
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
42
44
  }
43
45
  export interface ValueError {
44
46
  type: ValueErrorType;
package/errors/errors.js CHANGED
@@ -29,6 +29,7 @@ THE SOFTWARE.
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
31
31
  const Types = require("../typebox");
32
+ const index_1 = require("../format/index");
32
33
  // -------------------------------------------------------------------
33
34
  // ValueErrorType
34
35
  // -------------------------------------------------------------------
@@ -65,14 +66,16 @@ var ValueErrorType;
65
66
  ValueErrorType[ValueErrorType["StringMinLength"] = 28] = "StringMinLength";
66
67
  ValueErrorType[ValueErrorType["StringMaxLength"] = 29] = "StringMaxLength";
67
68
  ValueErrorType[ValueErrorType["StringPattern"] = 30] = "StringPattern";
68
- ValueErrorType[ValueErrorType["TupleZeroLength"] = 31] = "TupleZeroLength";
69
- ValueErrorType[ValueErrorType["TupleLength"] = 32] = "TupleLength";
70
- ValueErrorType[ValueErrorType["Undefined"] = 33] = "Undefined";
71
- ValueErrorType[ValueErrorType["Union"] = 34] = "Union";
72
- ValueErrorType[ValueErrorType["Uint8Array"] = 35] = "Uint8Array";
73
- ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 36] = "Uint8ArrayMinByteLength";
74
- ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 37] = "Uint8ArrayMaxByteLength";
75
- ValueErrorType[ValueErrorType["Void"] = 38] = "Void";
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";
76
79
  })(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
77
80
  // -------------------------------------------------------------------
78
81
  // ValueErrors
@@ -250,6 +253,17 @@ var ValueErrors;
250
253
  yield { type: ValueErrorType.StringPattern, schema, path, value, message: `Expected string to match pattern ${schema.pattern}` };
251
254
  }
252
255
  }
256
+ if (schema.format !== undefined) {
257
+ if (!index_1.Format.Has(schema.format)) {
258
+ yield { type: ValueErrorType.StringFormatUnknown, schema, path, value, message: `Unknown string format '${schema.format}'` };
259
+ }
260
+ else {
261
+ const format = index_1.Format.Get(schema.format);
262
+ if (!format(value)) {
263
+ yield { type: ValueErrorType.StringFormat, schema, path, value, message: `Expected string to match format '${schema.format}'` };
264
+ }
265
+ }
266
+ }
253
267
  }
254
268
  function* Tuple(schema, references, path, value) {
255
269
  if (!globalThis.Array.isArray(value)) {
@@ -2,7 +2,7 @@ export declare type FormatValidationFunction = (value: string) => boolean;
2
2
  /** Shared string formats used by the TypeCompiler and Value modules */
3
3
  export declare namespace Format {
4
4
  /** Clears all formats */
5
- function Clear(format: string): void;
5
+ function Clear(): void;
6
6
  /** Returns true if the string format exists */
7
7
  function Has(format: string): boolean;
8
8
  /** Sets a string format validation function */
package/format/format.js CHANGED
@@ -33,7 +33,7 @@ var Format;
33
33
  (function (Format) {
34
34
  const formats = new Map();
35
35
  /** Clears all formats */
36
- function Clear(format) {
36
+ function Clear() {
37
37
  return formats.clear();
38
38
  }
39
39
  Format.Clear = Clear;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.30",
3
+ "version": "0.24.33",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -65,11 +65,11 @@ License MIT
65
65
  - [Unsafe Types](#unsafe-types)
66
66
  - [Conditional Types](#conditional-types)
67
67
  - [Values](#values)
68
+ - [Formats](#formats)
68
69
  - [Guards](#guards)
69
70
  - [Strict](#strict)
70
71
  - [Validation](#validation)
71
72
  - [Compiler](#compiler)
72
- - [Formats](#formats)
73
73
  - [Benchmark](#benchmark)
74
74
  - [Contribute](#contribute)
75
75
 
@@ -688,8 +688,40 @@ const A = Value.Cast(T, null) // const A = { x: 0, y: 0 }
688
688
  const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0 }
689
689
 
690
690
  const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
691
+ ```
692
+
693
+ ## Formats
694
+
695
+ Use the format module to create user defined string formats. This module enables programmatic validation of strings that cannot be easily validated with [pattern](https://json-schema.org/understanding-json-schema/reference/regular_expressions.html) expressions. The format module is used by the Value and TypeCompiler modules only. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
696
+
697
+ The format module is an optional import.
698
+
699
+ ```typescript
700
+ import { Format } from '@sinclair/typebox/format'
701
+ ```
702
+
703
+ The following demonstrates its use.
704
+
705
+ ```typescript
706
+ //--------------------------------------------------------------------------------------------
707
+ //
708
+ // Use Format.Set(format, func) to define custom format
709
+ //
710
+ //--------------------------------------------------------------------------------------------
711
+
712
+ Format.Set('palindrome', value => value === value.split('').reverse().join(''))
713
+
714
+ //--------------------------------------------------------------------------------------------
715
+ //
716
+ // Use the format property on string types
717
+ //
718
+ //--------------------------------------------------------------------------------------------
691
719
 
720
+ const T = Type.String({ format: 'palindrome' })
692
721
 
722
+ Value.Check(T, 'kayak') // true
723
+
724
+ Value.Check(T, 'engine') // false
693
725
  ```
694
726
 
695
727
  ## Guards
@@ -818,7 +850,7 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
818
850
  z: Type.Number() // z: TNumber;
819
851
  })) // }>>
820
852
 
821
- const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
853
+ const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
822
854
  ```
823
855
 
824
856
  Validation errors can be read with the `Errors(...)` function.
@@ -862,38 +894,6 @@ console.log(C.Code()) // return function check(va
862
894
  // }
863
895
  ```
864
896
 
865
- ## Formats
866
-
867
- Use the `Format` module to define custom string formats.
868
-
869
- ```typescript
870
- import { Format } from '@sinclair/typebox/format'
871
- ```
872
-
873
- Formats are shared between `Value` and the `TypeCompiler` modules.
874
-
875
- ```typescript
876
- //--------------------------------------------------------------------------------------------
877
- //
878
- // Use Format.Set(...) to define a format
879
- //
880
- //--------------------------------------------------------------------------------------------
881
-
882
- Format.Set('ObjectId', value => /^[0-9a-fA-F]{24}$/.test(value))
883
-
884
- //--------------------------------------------------------------------------------------------
885
- //
886
- // The format is now available to TypeCompiler and Value modules
887
- //
888
- //--------------------------------------------------------------------------------------------
889
-
890
- const T = Type.String({ format: 'ObjectId' })
891
-
892
- const R1 = TypeCompiler.Compile(T).Check('507f1f77bcf86cd799439011')
893
-
894
- const R2 = Value.Check(T, '507f1f77bcf86cd799439011')
895
- ```
896
-
897
897
  ## Benchmark
898
898
 
899
899
  This project maintains a set of benchmarks that measure Ajv, Value and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.11.0.
package/value/cast.js CHANGED
@@ -80,6 +80,45 @@ class ValueCastUnknownTypeError extends Error {
80
80
  exports.ValueCastUnknownTypeError = ValueCastUnknownTypeError;
81
81
  var ValueCast;
82
82
  (function (ValueCast) {
83
+ // -----------------------------------------------------------
84
+ // Conversion
85
+ // -----------------------------------------------------------
86
+ function IsString(value) {
87
+ return typeof value === 'string';
88
+ }
89
+ function IsBoolean(value) {
90
+ return typeof value === 'boolean';
91
+ }
92
+ function IsBigInt(value) {
93
+ return typeof value === 'bigint';
94
+ }
95
+ function IsNumber(value) {
96
+ return typeof value === 'number';
97
+ }
98
+ function IsStringNumeric(value) {
99
+ return IsString(value) && !isNaN(value) && !isNaN(parseFloat(value));
100
+ }
101
+ function IsValueToString(value) {
102
+ return IsBigInt(value) || IsBoolean(value) || IsNumber(value);
103
+ }
104
+ function IsValueTrue(value) {
105
+ return value === true || (IsNumber(value) && value === 1) || (IsBigInt(value) && value === 1n) || (IsString(value) && (value.toLowerCase() === 'true' || value === '1'));
106
+ }
107
+ function TryConvertString(value) {
108
+ return IsValueToString(value) ? value.toString() : value;
109
+ }
110
+ function TryConvertNumber(value) {
111
+ return IsStringNumeric(value) ? parseFloat(value) : IsValueTrue(value) ? 1 : value;
112
+ }
113
+ function TryConvertInteger(value) {
114
+ return IsStringNumeric(value) ? parseInt(value) : IsValueTrue(value) ? 1 : value;
115
+ }
116
+ function TryConvertBoolean(value) {
117
+ return IsValueTrue(value) ? true : value;
118
+ }
119
+ // -----------------------------------------------------------
120
+ // Casts
121
+ // -----------------------------------------------------------
83
122
  function Any(schema, references, value) {
84
123
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
85
124
  }
@@ -91,7 +130,8 @@ var ValueCast;
91
130
  return value.map((val) => Visit(schema.items, references, val));
92
131
  }
93
132
  function Boolean(schema, references, value) {
94
- return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
133
+ const conversion = TryConvertBoolean(value);
134
+ return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
95
135
  }
96
136
  function Constructor(schema, references, value) {
97
137
  if (check_1.ValueCheck.Check(schema, references, value))
@@ -112,7 +152,8 @@ var ValueCast;
112
152
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
113
153
  }
114
154
  function Integer(schema, references, value) {
115
- return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
155
+ const conversion = TryConvertInteger(value);
156
+ return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
116
157
  }
117
158
  function Literal(schema, references, value) {
118
159
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
@@ -121,7 +162,8 @@ var ValueCast;
121
162
  return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
122
163
  }
123
164
  function Number(schema, references, value) {
124
- return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
165
+ const conversion = TryConvertNumber(value);
166
+ return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
125
167
  }
126
168
  function Object(schema, references, value) {
127
169
  if (check_1.ValueCheck.Check(schema, references, value))
@@ -169,7 +211,8 @@ var ValueCast;
169
211
  return Visit(reference, references, value);
170
212
  }
171
213
  function String(schema, references, value) {
172
- return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
214
+ const conversion = TryConvertString(value);
215
+ return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
173
216
  }
174
217
  function Tuple(schema, references, value) {
175
218
  if (check_1.ValueCheck.Check(schema, references, value))
package/value/value.d.ts CHANGED
@@ -10,9 +10,9 @@ export declare namespace Value {
10
10
  function Check<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): value is Types.Static<T>;
11
11
  /** Returns true if the value matches the given type. */
12
12
  function Check<T extends Types.TSchema>(schema: T, value: unknown): value is Types.Static<T>;
13
- /** Casts a value into a structure matching the given type. The result will be a new value that retains as much information of the original value as possible. */
13
+ /** 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. */
14
14
  function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): Types.Static<T>;
15
- /** Casts a value into a structure matching the given type. The result will be a new value that retains as much information of the original value as possible. */
15
+ /** 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. */
16
16
  function Cast<T extends Types.TSchema>(schema: T, value: unknown): Types.Static<T>;
17
17
  /** Returns an iterator for each error in this value. */
18
18
  function Errors<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): IterableIterator<ValueError>;