@sinclair/typebox 0.24.27 → 0.24.30

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.
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.Property = exports.TypeCheck = void 0;
31
31
  const index_1 = require("../errors/index");
32
32
  const index_2 = require("../guard/index");
33
+ const index_3 = require("../format/index");
33
34
  const Types = require("../typebox");
34
35
  // -------------------------------------------------------------------
35
36
  // TypeCheck
@@ -174,7 +175,7 @@ var TypeCompiler;
174
175
  yield `(Object.keys(${value}).length <= ${schema.maxProperties})`;
175
176
  const propertyKeys = globalThis.Object.keys(schema.properties);
176
177
  if (schema.additionalProperties === false) {
177
- // optimization: If the property key length matches the required keys length
178
+ // Optimization: If the property key length matches the required keys length
178
179
  // then we only need check that the values property key length matches that
179
180
  // of the property key length. This is because exhaustive testing for values
180
181
  // will occur in subsequent property tests.
@@ -210,6 +211,11 @@ var TypeCompiler;
210
211
  yield `(Object.values(${value}).every(value => ${expression}))`;
211
212
  }
212
213
  function* Ref(schema, value) {
214
+ // Reference: If we have seen this reference before we can just yield and return
215
+ // the function call. If this isn't the case we defer to visit to generate and
216
+ // set the function for subsequent passes. Consider for refactor.
217
+ if (names.has(schema.$ref))
218
+ return yield `(${CreateFunctionName(schema.$ref)}(${value}))`;
213
219
  if (!referenceMap.has(schema.$ref))
214
220
  throw Error(`TypeCompiler.Ref: Cannot de-reference schema with $id '${schema.$ref}'`);
215
221
  const reference = referenceMap.get(schema.$ref);
@@ -231,6 +237,9 @@ var TypeCompiler;
231
237
  const local = PushLocal(`new RegExp(/${schema.pattern}/);`);
232
238
  yield `(${local}.test(${value}))`;
233
239
  }
240
+ if (schema.format !== undefined) {
241
+ yield `(format('${schema.format}', ${value}))`;
242
+ }
234
243
  }
235
244
  function* Tuple(schema, value) {
236
245
  yield `(Array.isArray(${value}))`;
@@ -263,9 +272,9 @@ var TypeCompiler;
263
272
  yield `(${value} === null)`;
264
273
  }
265
274
  function* Visit(schema, value) {
266
- // reference: referenced schemas can originate from either additional
267
- // schemas or inline in the schema itself. Ideally the recursive
268
- // path should align to reference path. Consider for review.
275
+ // Reference: Referenced schemas can originate from either additional schemas
276
+ // or inline in the schema itself. Ideally the recursive path should align to
277
+ // reference path. Consider for refactor.
269
278
  if (schema.$id && !names.has(schema.$id)) {
270
279
  names.add(schema.$id);
271
280
  const name = CreateFunctionName(schema.$id);
@@ -377,8 +386,14 @@ var TypeCompiler;
377
386
  function Compile(schema, references = []) {
378
387
  index_2.TypeGuard.Assert(schema, references);
379
388
  const code = Build(schema, references);
380
- const func = globalThis.Function(code);
381
- return new TypeCheck(schema, references, func(), code);
389
+ const func1 = globalThis.Function('format', code);
390
+ const func2 = func1((format, value) => {
391
+ if (!index_3.Format.Has(format))
392
+ return false;
393
+ const func = index_3.Format.Get(format);
394
+ return func(value);
395
+ });
396
+ return new TypeCheck(schema, references, func2, code);
382
397
  }
383
398
  TypeCompiler.Compile = Compile;
384
399
  })(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
@@ -0,0 +1,12 @@
1
+ export declare type FormatValidationFunction = (value: string) => boolean;
2
+ /** Shared string formats used by the TypeCompiler and Value modules */
3
+ export declare namespace Format {
4
+ /** Clears all formats */
5
+ function Clear(format: string): void;
6
+ /** Returns true if the string format exists */
7
+ function Has(format: string): boolean;
8
+ /** Sets a string format validation function */
9
+ function Set(format: string, func: FormatValidationFunction): void;
10
+ /** Gets a string format validation function */
11
+ function Get(format: string): FormatValidationFunction | undefined;
12
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/format
5
+
6
+ The MIT License (MIT)
7
+
8
+ Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in
18
+ all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ THE SOFTWARE.
27
+
28
+ ---------------------------------------------------------------------------*/
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.Format = void 0;
31
+ /** Shared string formats used by the TypeCompiler and Value modules */
32
+ var Format;
33
+ (function (Format) {
34
+ const formats = new Map();
35
+ /** Clears all formats */
36
+ function Clear(format) {
37
+ return formats.clear();
38
+ }
39
+ Format.Clear = Clear;
40
+ /** Returns true if the string format exists */
41
+ function Has(format) {
42
+ return formats.has(format);
43
+ }
44
+ Format.Has = Has;
45
+ /** Sets a string format validation function */
46
+ function Set(format, func) {
47
+ formats.set(format, func);
48
+ }
49
+ Format.Set = Set;
50
+ /** Gets a string format validation function */
51
+ function Get(format) {
52
+ return formats.get(format);
53
+ }
54
+ Format.Get = Get;
55
+ })(Format = exports.Format || (exports.Format = {}));
@@ -0,0 +1 @@
1
+ export * from './format';
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/format
5
+
6
+ The MIT License (MIT)
7
+
8
+ Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in
18
+ all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ THE SOFTWARE.
27
+
28
+ ---------------------------------------------------------------------------*/
29
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ var desc = Object.getOwnPropertyDescriptor(m, k);
32
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
33
+ desc = { enumerable: true, get: function() { return m[k]; } };
34
+ }
35
+ Object.defineProperty(o, k2, desc);
36
+ }) : (function(o, m, k, k2) {
37
+ if (k2 === undefined) k2 = k;
38
+ o[k2] = m[k];
39
+ }));
40
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
41
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ __exportStar(require("./format"), exports);
package/guard/guard.js CHANGED
@@ -54,7 +54,7 @@ var TypeGuard;
54
54
  return false;
55
55
  }
56
56
  }
57
- function IsValidPropertyKey(value) {
57
+ function IsControlCharacterFree(value) {
58
58
  if (typeof value !== 'string')
59
59
  return false;
60
60
  for (let i = 0; i < value.length; i++) {
@@ -84,7 +84,10 @@ var TypeGuard;
84
84
  return value === undefined || (value !== undefined && IsString(value));
85
85
  }
86
86
  function IsOptionalPattern(value) {
87
- return value === undefined || (value !== undefined && IsString(value) && IsPattern(value));
87
+ return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value) && IsPattern(value));
88
+ }
89
+ function IsOptionalFormat(value) {
90
+ return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value));
88
91
  }
89
92
  /** Returns true if the given schema is TAny */
90
93
  function TAny(schema) {
@@ -181,7 +184,7 @@ var TypeGuard;
181
184
  return false;
182
185
  }
183
186
  for (const [key, value] of Object.entries(schema.properties)) {
184
- if (!IsValidPropertyKey(key))
187
+ if (!IsControlCharacterFree(key))
185
188
  return false;
186
189
  if (!TSchema(value))
187
190
  return false;
@@ -231,7 +234,7 @@ var TypeGuard;
231
234
  IsOptionalNumber(schema.minLength) &&
232
235
  IsOptionalNumber(schema.maxLength) &&
233
236
  IsOptionalPattern(schema.pattern) &&
234
- IsOptionalString(schema.format));
237
+ IsOptionalFormat(schema.format));
235
238
  }
236
239
  TypeGuard.TString = TString;
237
240
  /** Returns true if the given schema is TTuple */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.27",
3
+ "version": "0.24.30",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -26,15 +26,15 @@
26
26
  "publish": "hammer task publish"
27
27
  },
28
28
  "devDependencies": {
29
- "@sinclair/hammer": "^0.16.3",
30
- "@types/chai": "^4.3.0",
31
- "@types/mocha": "^9.1.0",
32
- "@types/node": "^17.0.12",
29
+ "@sinclair/hammer": "^0.17.1",
30
+ "@types/chai": "^4.3.3",
31
+ "@types/mocha": "^9.1.1",
32
+ "@types/node": "^18.7.13",
33
33
  "ajv": "^8.11.0",
34
34
  "ajv-formats": "^2.1.1",
35
- "chai": "^4.3.5",
36
- "mocha": "^9.2.0",
35
+ "chai": "^4.3.6",
36
+ "mocha": "^9.2.2",
37
37
  "prettier": "^2.7.1",
38
- "typescript": "^4.7.4"
38
+ "typescript": "^4.8.2"
39
39
  }
40
40
  }
package/readme.md CHANGED
@@ -19,16 +19,16 @@
19
19
 
20
20
  ## Install
21
21
 
22
- #### Node
22
+ Node
23
23
 
24
24
  ```bash
25
25
  $ npm install @sinclair/typebox --save
26
26
  ```
27
27
 
28
- #### Deno
28
+ Deno and ESM
29
29
 
30
30
  ```typescript
31
- import { Static, Type } from 'https://deno.land/x/typebox/src/typebox.ts'
31
+ import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
32
32
  ```
33
33
 
34
34
  ## Example
@@ -45,9 +45,9 @@ type T = Static<typeof T> // type T = string
45
45
 
46
46
  ## Overview
47
47
 
48
- TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create unified types that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
48
+ TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
49
49
 
50
- TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire.
50
+ TypeBox is designed to enable JSON schema to compose with the same flexibility as TypeScript's type system. It can be used either as a simple tool to build up complex schemas or integrated into REST and RPC services to help validate data received over the wire.
51
51
 
52
52
  License MIT
53
53
 
@@ -69,6 +69,7 @@ License MIT
69
69
  - [Strict](#strict)
70
70
  - [Validation](#validation)
71
71
  - [Compiler](#compiler)
72
+ - [Formats](#formats)
72
73
  - [Benchmark](#benchmark)
73
74
  - [Contribute](#contribute)
74
75
 
@@ -554,7 +555,7 @@ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
554
555
  type T = Static<typeof T> // type T = string
555
556
  ```
556
557
 
557
- The `Type.Unsafe(...)` function can be used to create schemas for validators that require specific schema representations. An example of this would be OpenAPI's `nullable` and `enum` schemas which are not provided by TypeBox. The following demonstrates using `Type.Unsafe(...)` to create these types.
558
+ This function can be used to create custom schemas for validators that require specific schema representations. An example of this might be OpenAPI's `nullable` and `enum` schemas which are not provided by TypeBox. The following demonstrates using `Type.Unsafe(...)` to create these types.
558
559
 
559
560
  ```typescript
560
561
  import { Type, Static, TSchema } from '@sinclair/typebox'
@@ -596,7 +597,9 @@ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
596
597
 
597
598
  ## Conditional Types
598
599
 
599
- Use the `Conditional` module to create conditionally mapped types.
600
+ Use the conditional module to create [Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html). This module implements TypeScript's structural equivalence checks to enable TypeBox types to be conditionally inferred at runtime. This module also provides the [Extract](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) and [Exclude](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers) utility types which are expressed as conditional types in TypeScript.
601
+
602
+ The conditional module is provided as an optional import.
600
603
 
601
604
  ```typescript
602
605
  import { Conditional } from '@sinclair/typebox/conditional'
@@ -645,12 +648,18 @@ The following table shows the TypeBox mappings between TypeScript and JSON schem
645
648
 
646
649
  ## Values
647
650
 
648
- Use the `Value` module to perform type operations on values.
651
+ Use the value module to perform common type operations on values. This module provides functionality to create, check and cast values into a given type. Note that this module internally uses dynamic type checking to perform these operations. For faster type checking performance, consider using either Ajv or the TypeBox [TypeCompiler](#compiler).
652
+
653
+ The value module is provided as an optional import.
649
654
 
650
655
  ```typescript
651
656
  import { Value } from '@sinclair/typebox/value'
657
+ ```
658
+ The following demonstrates its use.
659
+ ```typescript
652
660
 
653
- const T = Type.Object({ x: Type.Number(), y: Type.Number() })
661
+
662
+ const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
654
663
 
655
664
  //--------------------------------------------------------------------------------------------
656
665
  //
@@ -685,7 +694,7 @@ const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
685
694
 
686
695
  ## Guards
687
696
 
688
- Use the `TypeGuard` module to test if values are valid TypeBox types.
697
+ Use the guard module to test if values are TypeBox types.
689
698
 
690
699
  ```typescript
691
700
  import { TypeGuard } from '@sinclair/typebox/guard'
@@ -792,7 +801,9 @@ Please refer to the official Ajv [documentation](https://ajv.js.org/guide/gettin
792
801
 
793
802
  ## Compiler
794
803
 
795
- TypeBox provides an optional high performance runtime compiler and type checker that can be used in applications that require extremely fast validation. This compiler is optimized for TypeBox types whose schematics are known in advance. If defining custom types with `Type.Unsafe<T>` please consider Ajv.
804
+ TypeBox provides an optional high performance just-in-time (JIT) compiler and type checker that can be used in applications that require extremely fast validation. Note that this compiler is optimized for TypeBox types only where the schematics are known in advance. If defining custom types with `Type.Unsafe<T>` please consider Ajv.
805
+
806
+ The compiler module is provided as an optional import.
796
807
 
797
808
  ```typescript
798
809
  import { TypeCompiler } from '@sinclair/typebox/compiler'
@@ -851,11 +862,41 @@ console.log(C.Code()) // return function check(va
851
862
  // }
852
863
  ```
853
864
 
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))
854
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
+ ```
855
896
 
856
897
  ## Benchmark
857
898
 
858
- This project maintains a set of benchmarks that measure Ajv 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.
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.
859
900
 
860
901
  For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/).
861
902
 
@@ -867,29 +908,29 @@ This benchmark measures compilation performance for varying types. You can revie
867
908
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
868
909
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
869
910
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
870
- │ Number │ 2000 │ ' 394 ms' │ ' 9 ms' │ ' 43.78 x' │
871
- │ String │ 2000 │ ' 320 ms' │ ' 9 ms' │ ' 35.56 x' │
872
- │ Boolean │ 2000 │ ' 326 ms' │ ' 6 ms' │ ' 54.33 x' │
873
- │ Null │ 2000 │ ' 256 ms' │ ' 6 ms' │ ' 42.67 x' │
874
- │ RegEx │ 2000 │ ' 494 ms' │ ' 12 ms' │ ' 41.17 x' │
875
- │ ObjectA │ 2000 │ ' 2813 ms' │ ' 41 ms' │ ' 68.61 x' │
876
- │ ObjectB │ 2000 │ ' 2949 ms' │ ' 30 ms' │ ' 98.30 x' │
877
- │ Tuple │ 2000 │ ' 1258 ms' │ ' 19 ms' │ ' 66.21 x' │
878
- │ Union │ 2000 │ ' 1308 ms' │ ' 22 ms' │ ' 59.45 x' │
879
- │ Vector4 │ 2000 │ ' 1589 ms' │ ' 17 ms' │ ' 93.47 x' │
880
- │ Matrix4 │ 2000 │ ' 932 ms' │ ' 11 ms' │ ' 84.73 x' │
881
- │ Literal_String │ 2000 │ ' 343 ms' │ ' 6 ms' │ ' 57.17 x' │
882
- │ Literal_Number │ 2000 │ ' 380 ms' │ ' 6 ms' │ ' 63.33 x' │
883
- │ Literal_Boolean │ 2000 │ ' 369 ms' │ ' 4 ms' │ ' 92.25 x' │
884
- │ Array_Number │ 2000 │ ' 730 ms' │ ' 6 ms' │ ' 121.67 x' │
885
- │ Array_String │ 2000 │ ' 764 ms' │ ' 7 ms' │ ' 109.14 x' │
886
- │ Array_Boolean │ 2000 │ ' 791 ms' │ ' 8 ms' │ ' 98.88 x' │
887
- │ Array_ObjectA │ 2000 │ ' 3550 ms' │ ' 33 ms' │ ' 107.58 x' │
888
- │ Array_ObjectB │ 2000 │ ' 3709 ms' │ ' 33 ms' │ ' 112.39 x' │
889
- │ Array_Tuple │ 2000 │ ' 2209 ms' │ ' 15 ms' │ ' 147.27 x' │
890
- │ Array_Union │ 2000 │ ' 1733 ms' │ ' 18 ms' │ ' 96.28 x' │
891
- │ Array_Vector4 │ 2000 │ ' 2279 ms' │ ' 16 ms' │ ' 142.44 x' │
892
- │ Array_Matrix4 │ 2000 │ ' 1587 ms' │ ' 11 ms' │ ' 144.27 x' │
911
+ │ Number │ 2000 │ ' 402 ms' │ ' 8 ms' │ ' 50.25 x' │
912
+ │ String │ 2000 │ ' 316 ms' │ ' 8 ms' │ ' 39.50 x' │
913
+ │ Boolean │ 2000 │ ' 308 ms' │ ' 6 ms' │ ' 51.33 x' │
914
+ │ Null │ 2000 │ ' 259 ms' │ ' 5 ms' │ ' 51.80 x' │
915
+ │ RegEx │ 2000 │ ' 479 ms' │ ' 11 ms' │ ' 43.55 x' │
916
+ │ ObjectA │ 2000 │ ' 2766 ms' │ ' 41 ms' │ ' 67.46 x' │
917
+ │ ObjectB │ 2000 │ ' 3062 ms' │ ' 29 ms' │ ' 105.59 x' │
918
+ │ Tuple │ 2000 │ ' 1258 ms' │ ' 21 ms' │ ' 59.90 x' │
919
+ │ Union │ 2000 │ ' 1449 ms' │ ' 29 ms' │ ' 49.97 x' │
920
+ │ Vector4 │ 2000 │ ' 1616 ms' │ ' 16 ms' │ ' 101.00 x' │
921
+ │ Matrix4 │ 2000 │ ' 975 ms' │ ' 8 ms' │ ' 121.88 x' │
922
+ │ Literal_String │ 2000 │ ' 350 ms' │ ' 6 ms' │ ' 58.33 x' │
923
+ │ Literal_Number │ 2000 │ ' 386 ms' │ ' 5 ms' │ ' 77.20 x' │
924
+ │ Literal_Boolean │ 2000 │ ' 377 ms' │ ' 4 ms' │ ' 94.25 x' │
925
+ │ Array_Number │ 2000 │ ' 737 ms' │ ' 7 ms' │ ' 105.29 x' │
926
+ │ Array_String │ 2000 │ ' 765 ms' │ ' 7 ms' │ ' 109.29 x' │
927
+ │ Array_Boolean │ 2000 │ ' 783 ms' │ ' 8 ms' │ ' 97.88 x' │
928
+ │ Array_ObjectA │ 2000 │ ' 3578 ms' │ ' 31 ms' │ ' 115.42 x' │
929
+ │ Array_ObjectB │ 2000 │ ' 3718 ms' │ ' 33 ms' │ ' 112.67 x' │
930
+ │ Array_Tuple │ 2000 │ ' 2259 ms' │ ' 14 ms' │ ' 161.36 x' │
931
+ │ Array_Union │ 2000 │ ' 1704 ms' │ ' 20 ms' │ ' 85.20 x' │
932
+ │ Array_Vector4 │ 2000 │ ' 2293 ms' │ ' 17 ms' │ ' 134.88 x' │
933
+ │ Array_Matrix4 │ 2000 │ ' 1575 ms' │ ' 12 ms' │ ' 131.25 x' │
893
934
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
894
935
  ```
895
936
 
@@ -901,47 +942,48 @@ This benchmark measures validation performance for varying types. You can review
901
942
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
902
943
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
903
944
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
904
- │ Number │ 1000000 │ ' 27 ms' │ ' 6 ms' │ ' 4 ms' │ ' 1.50 x' │
905
- │ String │ 1000000 │ ' 23 ms' │ ' 20 ms' │ ' 11 ms' │ ' 1.82 x' │
906
- │ Boolean │ 1000000 │ ' 21 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │
907
- │ Null │ 1000000 │ ' 24 ms' │ ' 18 ms' │ ' 10 ms' │ ' 1.80 x' │
908
- │ RegEx │ 1000000 │ ' 170 ms' │ ' 43 ms' │ ' 36 ms' │ ' 1.19 x' │
909
- │ ObjectA │ 1000000 │ ' 567 ms' │ ' 34 ms' │ ' 23 ms' │ ' 1.48 x' │
910
- │ ObjectB │ 1000000 │ ' 985 ms' │ ' 50 ms' │ ' 36 ms' │ ' 1.39 x' │
911
- │ Tuple │ 1000000 │ ' 119 ms' │ ' 24 ms' │ ' 14 ms' │ ' 1.71 x' │
912
- │ Union │ 1000000 │ ' 302 ms' │ ' 26 ms' │ ' 14 ms' │ ' 1.86 x' │
913
- │ Recursive │ 1000000 │ ' 3071 ms' │ ' 397 ms' │ ' 177 ms' │ ' 2.24 x' │
914
- │ Vector4 │ 1000000 │ ' 135 ms' │ ' 24 ms' │ ' 11 ms' │ ' 2.18 x' │
915
- │ Matrix4 │ 1000000 │ ' 632 ms' │ ' 41 ms' │ ' 30 ms' │ ' 1.37 x' │
916
- │ Literal_String │ 1000000 │ ' 49 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
917
- │ Literal_Number │ 1000000 │ ' 56 ms' │ ' 18 ms' │ ' 9 ms' │ ' 2.00 x' │
918
- │ Literal_Boolean │ 1000000 │ ' 56 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
919
- │ Array_Number │ 1000000 │ ' 408 ms' │ ' 31 ms' │ ' 17 ms' │ ' 1.82 x' │
920
- │ Array_String │ 1000000 │ ' 458 ms' │ ' 32 ms' │ ' 20 ms' │ ' 1.60 x' │
921
- │ Array_Boolean │ 1000000 │ ' 431 ms' │ ' 34 ms' │ ' 24 ms' │ ' 1.42 x' │
922
- │ Array_ObjectA │ 1000000 │ ' 13322 ms' │ ' 2549 ms' │ ' 1636 ms' │ ' 1.56 x' │
923
- │ Array_ObjectB │ 1000000 │ ' 16341 ms' │ ' 2865 ms' │ ' 2074 ms' │ ' 1.38 x' │
924
- │ Array_Tuple │ 1000000 │ ' 1640 ms' │ ' 92 ms' │ ' 71 ms' │ ' 1.30 x' │
925
- │ Array_Union │ 1000000 │ ' 4803 ms' │ ' 237 ms' │ ' 89 ms' │ ' 2.66 x' │
926
- │ Array_Recursive │ 1000000 │ ' 53759 ms' │ ' 7694 ms' │ ' 2600 ms' │ ' 2.96 x' │
927
- │ Array_Vector4 │ 1000000 │ ' 2099 ms' │ ' 96 ms' │ ' 52 ms' │ ' 1.85 x' │
928
- │ Array_Matrix4 │ 1000000 │ ' 11436 ms' │ ' 384 ms' │ ' 310 ms' │ ' 1.24 x' │
945
+ │ Number │ 1000000 │ ' 38 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │
946
+ │ String │ 1000000 │ ' 26 ms' │ ' 23 ms' │ ' 12 ms' │ ' 1.92 x' │
947
+ │ Boolean │ 1000000 │ ' 26 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │
948
+ │ Null │ 1000000 │ ' 29 ms' │ ' 24 ms' │ ' 12 ms' │ ' 2.00 x' │
949
+ │ RegEx │ 1000000 │ ' 169 ms' │ ' 47 ms' │ ' 37 ms' │ ' 1.27 x' │
950
+ │ ObjectA │ 1000000 │ ' 551 ms' │ ' 45 ms' │ ' 23 ms' │ ' 1.96 x' │
951
+ │ ObjectB │ 1000000 │ ' 995 ms' │ ' 49 ms' │ ' 39 ms' │ ' 1.26 x' │
952
+ │ Tuple │ 1000000 │ ' 115 ms' │ ' 30 ms' │ ' 14 ms' │ ' 2.14 x' │
953
+ │ Union │ 1000000 │ ' 294 ms' │ ' 30 ms' │ ' 14 ms' │ ' 2.14 x' │
954
+ │ Recursive │ 1000000 │ ' 3308 ms' │ ' 429 ms' │ ' 174 ms' │ ' 2.47 x' │
955
+ │ Vector4 │ 1000000 │ ' 145 ms' │ ' 25 ms' │ ' 13 ms' │ ' 1.92 x' │
956
+ │ Matrix4 │ 1000000 │ ' 663 ms' │ ' 42 ms' │ ' 34 ms' │ ' 1.24 x' │
957
+ │ Literal_String │ 1000000 │ ' 46 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
958
+ │ Literal_Number │ 1000000 │ ' 50 ms' │ ' 26 ms' │ ' 11 ms' │ ' 2.36 x' │
959
+ │ Literal_Boolean │ 1000000 │ ' 45 ms' │ ' 24 ms' │ ' 11 ms' │ ' 2.18 x' │
960
+ │ Array_Number │ 1000000 │ ' 411 ms' │ ' 35 ms' │ ' 19 ms' │ ' 1.84 x' │
961
+ │ Array_String │ 1000000 │ ' 438 ms' │ ' 33 ms' │ ' 20 ms' │ ' 1.65 x' │
962
+ │ Array_Boolean │ 1000000 │ ' 444 ms' │ ' 38 ms' │ ' 24 ms' │ ' 1.58 x' │
963
+ │ Array_ObjectA │ 1000000 │ ' 13714 ms' │ ' 2819 ms' │ ' 1791 ms' │ ' 1.57 x' │
964
+ │ Array_ObjectB │ 1000000 │ ' 15855 ms' │ ' 2965 ms' │ ' 2066 ms' │ ' 1.44 x' │
965
+ │ Array_Tuple │ 1000000 │ ' 1682 ms' │ ' 94 ms' │ ' 71 ms' │ ' 1.32 x' │
966
+ │ Array_Union │ 1000000 │ ' 4575 ms' │ ' 239 ms' │ ' 86 ms' │ ' 2.78 x' │
967
+ │ Array_Recursive │ 1000000 │ ' 51970 ms' │ ' 7192 ms' │ ' 2617 ms' │ ' 2.75 x' │
968
+ │ Array_Vector4 │ 1000000 │ ' 2097 ms' │ ' 100 ms' │ ' 54 ms' │ ' 1.85 x' │
969
+ │ Array_Matrix4 │ 1000000 │ ' 11596 ms' │ ' 381 ms' │ ' 327 ms' │ ' 1.17 x' │
929
970
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
930
971
  ```
931
972
 
932
973
  ### Compression
933
974
 
934
- The following table lists esbuild compiled and minified sizes for each TypeBox import.
975
+ The following table lists esbuild compiled and minified sizes for each TypeBox module.
935
976
 
936
977
  ```typescript
937
978
  ┌──────────────────────┬────────────┬────────────┬─────────────┐
938
979
  │ (index) │ Compiled │ Minified │ Compression │
939
980
  ├──────────────────────┼────────────┼────────────┼─────────────┤
940
- │ typebox/compiler │ ' 47 kb' │ ' 23 kb' │ '1.99 x' │
941
- │ typebox/conditional │ ' 41 kb' │ ' 16 kb' │ '2.46 x' │
942
- │ typebox/guard │ ' 20 kb' │ ' 9 kb' │ '2.06 x' │
943
- │ typebox/value │ ' 54 kb' │ ' 25 kb' │ '2.14 x' │
944
- │ typebox │ ' 11 kb' │ ' 5 kb' │ '1.89 x' │
981
+ │ typebox/compiler │ ' 48 kb' │ ' 24 kb' │ '2.00 x' │
982
+ │ typebox/conditional │ ' 41 kb' │ ' 16 kb' │ '2.47 x' │
983
+ │ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.68 x' │
984
+ │ typebox/guard │ ' 20 kb' │ ' 9 kb' │ '2.08 x' │
985
+ │ typebox/value │ ' 55 kb' │ ' 25 kb' │ '2.15 x' │
986
+ │ typebox │ ' 11 kb' │ ' 5 kb' │ '1.91 x' │
945
987
  └──────────────────────┴────────────┴────────────┴─────────────┘
946
988
  ```
947
989
 
package/value/check.js CHANGED
@@ -29,6 +29,7 @@ THE SOFTWARE.
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
31
31
  const Types = require("../typebox");
32
+ const format_1 = require("../format");
32
33
  class ValueCheckUnknownTypeError extends Error {
33
34
  constructor(schema) {
34
35
  super('ValueCheck: Unknown type');
@@ -205,6 +206,12 @@ var ValueCheck;
205
206
  if (!regex.test(value))
206
207
  return false;
207
208
  }
209
+ if (schema.format !== undefined) {
210
+ if (!format_1.Format.Has(schema.format))
211
+ return false;
212
+ const func = format_1.Format.Get(schema.format);
213
+ return func(value);
214
+ }
208
215
  return true;
209
216
  }
210
217
  function Tuple(schema, references, value) {
package/value/create.js CHANGED
@@ -213,6 +213,14 @@ var ValueCreate;
213
213
  return schema.default;
214
214
  }
215
215
  }
216
+ else if (schema.format !== undefined) {
217
+ if (schema.default === undefined) {
218
+ throw new Error('ValueCreate.String: String types with formats must specify a default value');
219
+ }
220
+ else {
221
+ return schema.default;
222
+ }
223
+ }
216
224
  else {
217
225
  if (schema.default !== undefined) {
218
226
  return schema.default;
package/value/value.d.ts CHANGED
@@ -6,9 +6,9 @@ export declare namespace Value {
6
6
  function Create<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R]): Types.Static<T>;
7
7
  /** Creates a value from the given type */
8
8
  function Create<T extends Types.TSchema>(schema: T): Types.Static<T>;
9
- /** Checks a value matches the given type */
9
+ /** Returns true if the value matches the given type. */
10
10
  function Check<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): value is Types.Static<T>;
11
- /** Checks a value matches the given type */
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
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. */
14
14
  function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): Types.Static<T>;