@sinclair/typebox 0.25.22 → 0.25.24
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.
- package/compiler/compiler.js +3 -0
- package/errors/errors.js +4 -0
- package/guard/extends.d.ts +10 -0
- package/guard/extends.js +50 -0
- package/guard/index.d.ts +1 -0
- package/guard/index.js +1 -0
- package/package.json +1 -1
- package/readme.md +109 -197
- package/typebox.d.ts +5 -10
- package/value/cast.js +0 -5
- package/value/check.js +10 -0
- package/value/create.js +0 -10
package/compiler/compiler.js
CHANGED
|
@@ -263,6 +263,9 @@ var TypeCompiler;
|
|
|
263
263
|
const propertySchema = schema.properties[propertyKey];
|
|
264
264
|
if (schema.required && schema.required.includes(propertyKey)) {
|
|
265
265
|
yield* Visit(propertySchema, memberExpression);
|
|
266
|
+
if (index_3.TypeExtends.Undefined(propertySchema)) {
|
|
267
|
+
yield `('${propertyKey}' in ${value})`;
|
|
268
|
+
}
|
|
266
269
|
}
|
|
267
270
|
else {
|
|
268
271
|
const expression = CreateExpression(propertySchema, memberExpression);
|
package/errors/errors.js
CHANGED
|
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
|
|
31
31
|
const Types = require("../typebox");
|
|
32
32
|
const index_1 = require("../system/index");
|
|
33
|
+
const extends_1 = require("../guard/extends");
|
|
33
34
|
const index_2 = require("../format/index");
|
|
34
35
|
const index_3 = require("../custom/index");
|
|
35
36
|
const index_4 = require("../hash/index");
|
|
@@ -269,6 +270,9 @@ var ValueErrors;
|
|
|
269
270
|
const propertySchema = schema.properties[propertyKey];
|
|
270
271
|
if (schema.required && schema.required.includes(propertyKey)) {
|
|
271
272
|
yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
|
|
273
|
+
if (extends_1.TypeExtends.Undefined(schema) && !(propertyKey in value)) {
|
|
274
|
+
yield { type: ValueErrorType.ObjectRequiredProperties, schema: propertySchema, path: `${path}/${propertyKey}`, value: undefined, message: `Expected required property` };
|
|
275
|
+
}
|
|
272
276
|
}
|
|
273
277
|
else {
|
|
274
278
|
if (value[propertyKey] !== undefined) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Types from '../typebox';
|
|
2
|
+
export declare namespace TypeExtends {
|
|
3
|
+
/**
|
|
4
|
+
* This function returns true if the given schema is undefined, either directly or
|
|
5
|
+
* through union composition. This check is required on object property types of
|
|
6
|
+
* undefined, where an additional `'x' in value` check is required to determine
|
|
7
|
+
* the keys existence.
|
|
8
|
+
*/
|
|
9
|
+
function Undefined(schema: Types.TSchema): boolean;
|
|
10
|
+
}
|
package/guard/extends.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/guard
|
|
5
|
+
|
|
6
|
+
The MIT License (MIT)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2017-2023 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, dTribute, 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.TypeExtends = void 0;
|
|
31
|
+
const Types = require("../typebox");
|
|
32
|
+
var TypeExtends;
|
|
33
|
+
(function (TypeExtends) {
|
|
34
|
+
/**
|
|
35
|
+
* This function returns true if the given schema is undefined, either directly or
|
|
36
|
+
* through union composition. This check is required on object property types of
|
|
37
|
+
* undefined, where an additional `'x' in value` check is required to determine
|
|
38
|
+
* the keys existence.
|
|
39
|
+
*/
|
|
40
|
+
function Undefined(schema) {
|
|
41
|
+
if (schema[Types.Kind] === 'Undefined')
|
|
42
|
+
return true;
|
|
43
|
+
if (schema[Types.Kind] === 'Union') {
|
|
44
|
+
const union = schema;
|
|
45
|
+
return union.anyOf.some((schema) => Undefined(schema));
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
TypeExtends.Undefined = Undefined;
|
|
50
|
+
})(TypeExtends = exports.TypeExtends || (exports.TypeExtends = {}));
|
package/guard/index.d.ts
CHANGED
package/guard/index.js
CHANGED
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
#### Npm
|
|
23
23
|
```bash
|
|
24
24
|
$ npm install @sinclair/typebox --save
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
#### Deno
|
|
28
28
|
```typescript
|
|
29
29
|
import { Static, Type } from 'npm:@sinclair/typebox'
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
#### Esm
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
35
35
|
import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
|
|
@@ -64,7 +64,7 @@ type T = Static<typeof T> // type T = {
|
|
|
64
64
|
|
|
65
65
|
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.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
This library 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.
|
|
68
68
|
|
|
69
69
|
License MIT
|
|
70
70
|
|
|
@@ -96,8 +96,8 @@ License MIT
|
|
|
96
96
|
- [Errors](#values-errors)
|
|
97
97
|
- [Pointer](#values-pointer)
|
|
98
98
|
- [TypeCheck](#typecheck)
|
|
99
|
-
- [TypeCompiler](#typecheck-typecompiler)
|
|
100
99
|
- [Ajv](#typecheck-ajv)
|
|
100
|
+
- [TypeCompiler](#typecheck-typecompiler)
|
|
101
101
|
- [TypeSystem](#typecheck)
|
|
102
102
|
- [Types](#typesystem-types)
|
|
103
103
|
- [Formats](#typesystem-formats)
|
|
@@ -933,17 +933,58 @@ ValuePointer.Set(A, '/z', 1) // const A = { x: 1, y: 1,
|
|
|
933
933
|
|
|
934
934
|
## TypeCheck
|
|
935
935
|
|
|
936
|
-
TypeBox
|
|
936
|
+
TypeBox constructs JSON Schema draft 6 compliant schematics and can be used with any validator that supports this specification. In JavaScript, an ideal validator to use is Ajv which supports draft 6 as well as more recent revisions to the specification. In addition to Ajv, TypeBox provides an optional built in type compiler which can offer faster runtime type compilation, as well as providing high performance data validation for TypeBox types only.
|
|
937
937
|
|
|
938
938
|
The following sections detail using these validators.
|
|
939
939
|
|
|
940
|
+
<a name='typecheck-ajv'></a>
|
|
941
|
+
|
|
942
|
+
## Ajv
|
|
943
|
+
|
|
944
|
+
The following shows the recommended setup for Ajv.
|
|
945
|
+
|
|
946
|
+
```bash
|
|
947
|
+
$ npm install ajv ajv-formats --save
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
```typescript
|
|
951
|
+
import { Type } from '@sinclair/typebox'
|
|
952
|
+
import addFormats from 'ajv-formats'
|
|
953
|
+
import Ajv from 'ajv'
|
|
954
|
+
|
|
955
|
+
const ajv = addFormats(new Ajv({}), [
|
|
956
|
+
'date-time',
|
|
957
|
+
'time',
|
|
958
|
+
'date',
|
|
959
|
+
'email',
|
|
960
|
+
'hostname',
|
|
961
|
+
'ipv4',
|
|
962
|
+
'ipv6',
|
|
963
|
+
'uri',
|
|
964
|
+
'uri-reference',
|
|
965
|
+
'uuid',
|
|
966
|
+
'uri-template',
|
|
967
|
+
'json-pointer',
|
|
968
|
+
'relative-json-pointer',
|
|
969
|
+
'regex'
|
|
970
|
+
])
|
|
971
|
+
|
|
972
|
+
const C = ajv.compile(Type.Object({
|
|
973
|
+
x: Type.Number(),
|
|
974
|
+
y: Type.Number(),
|
|
975
|
+
z: Type.Number()
|
|
976
|
+
}))
|
|
977
|
+
|
|
978
|
+
const R = C({ x: 1, y: 2, z: 3 }) // const R = true
|
|
979
|
+
```
|
|
980
|
+
|
|
940
981
|
<a name='typecheck-typecompiler'></a>
|
|
941
982
|
|
|
942
983
|
### TypeCompiler
|
|
943
984
|
|
|
944
|
-
|
|
985
|
+
The TypeCompiler is a Just-In-Time (JIT) runtime compiler that can be used to convert TypeBox types into fast validation routines. This compiler is specifically tuned for fast compilation and validation for TypeBox types only.
|
|
945
986
|
|
|
946
|
-
The
|
|
987
|
+
The TypeCompiler is provided as an optional import.
|
|
947
988
|
|
|
948
989
|
```typescript
|
|
949
990
|
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
|
@@ -961,7 +1002,7 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
|
|
|
961
1002
|
const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
|
|
962
1003
|
```
|
|
963
1004
|
|
|
964
|
-
|
|
1005
|
+
Use `Errors(...)` to generate diagnostics for a value. The `Errors(...)` function will run an exhaustive check across the value and yield any error found. For performance, this function should only be called after failed `Check(...)`.
|
|
965
1006
|
|
|
966
1007
|
```typescript
|
|
967
1008
|
const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
|
|
@@ -1002,141 +1043,11 @@ console.log(C.Code()) // return function check(va
|
|
|
1002
1043
|
// }
|
|
1003
1044
|
```
|
|
1004
1045
|
|
|
1005
|
-
<a name='typecheck-ajv'></a>
|
|
1006
|
-
|
|
1007
|
-
### Ajv
|
|
1008
|
-
|
|
1009
|
-
The following are the recommended configurations to support both the [Standard](#standard) and [Extended](#extended) type sets provided by TypeBox. For schema portability and publishing to remote systems, it is recommended to use the Standard type set only.
|
|
1010
|
-
|
|
1011
|
-
```bash
|
|
1012
|
-
$ npm install ajv ajv-formats --save
|
|
1013
|
-
```
|
|
1014
|
-
|
|
1015
|
-
<details>
|
|
1016
|
-
|
|
1017
|
-
<summary>
|
|
1018
|
-
<strong>Standard Ajv Configuration</strong>
|
|
1019
|
-
<p>Expand for Standard Type Set Configuration</p>
|
|
1020
|
-
</summary>
|
|
1021
|
-
|
|
1022
|
-
```typescript
|
|
1023
|
-
import { Type } from '@sinclair/typebox'
|
|
1024
|
-
import addFormats from 'ajv-formats'
|
|
1025
|
-
import Ajv from 'ajv'
|
|
1026
|
-
|
|
1027
|
-
export function createAjv() {
|
|
1028
|
-
return addFormats(new Ajv({}), [
|
|
1029
|
-
'date-time',
|
|
1030
|
-
'time',
|
|
1031
|
-
'date',
|
|
1032
|
-
'email',
|
|
1033
|
-
'hostname',
|
|
1034
|
-
'ipv4',
|
|
1035
|
-
'ipv6',
|
|
1036
|
-
'uri',
|
|
1037
|
-
'uri-reference',
|
|
1038
|
-
'uuid',
|
|
1039
|
-
'uri-template',
|
|
1040
|
-
'json-pointer',
|
|
1041
|
-
'relative-json-pointer',
|
|
1042
|
-
'regex'
|
|
1043
|
-
])
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
const ajv = createAjv()
|
|
1047
|
-
|
|
1048
|
-
const R = ajv.validate(Type.Object({ // const R = true
|
|
1049
|
-
x: Type.Number(),
|
|
1050
|
-
y: Type.Number(),
|
|
1051
|
-
z: Type.Number()
|
|
1052
|
-
}), { x: 1, y: 2, z: 3 })
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
</details>
|
|
1056
|
-
|
|
1057
|
-
<details>
|
|
1058
|
-
|
|
1059
|
-
<summary>
|
|
1060
|
-
<strong>Extended Ajv Configuration</strong>
|
|
1061
|
-
<p>Expand for Extended Type Set Configuration</p>
|
|
1062
|
-
</summary>
|
|
1063
|
-
|
|
1064
|
-
```typescript
|
|
1065
|
-
import { TypeGuard } from '@sinclair/typebox/guard'
|
|
1066
|
-
import { Value } from '@sinclair/typebox/value'
|
|
1067
|
-
import { Type } from '@sinclair/typebox'
|
|
1068
|
-
import addFormats from 'ajv-formats'
|
|
1069
|
-
import Ajv from 'ajv'
|
|
1070
|
-
|
|
1071
|
-
function schemaOf(schemaOf: string, value: unknown, schema: unknown) {
|
|
1072
|
-
switch (schemaOf) {
|
|
1073
|
-
case 'Constructor':
|
|
1074
|
-
return TypeGuard.TConstructor(schema) && Value.Check(schema, value) // not supported
|
|
1075
|
-
case 'Function':
|
|
1076
|
-
return TypeGuard.TFunction(schema) && Value.Check(schema, value) // not supported
|
|
1077
|
-
case 'Date':
|
|
1078
|
-
return TypeGuard.TDate(schema) && Value.Check(schema, value)
|
|
1079
|
-
case 'Promise':
|
|
1080
|
-
return TypeGuard.TPromise(schema) && Value.Check(schema, value) // not supported
|
|
1081
|
-
case 'Uint8Array':
|
|
1082
|
-
return TypeGuard.TUint8Array(schema) && Value.Check(schema, value)
|
|
1083
|
-
case 'Undefined':
|
|
1084
|
-
return TypeGuard.TUndefined(schema) && Value.Check(schema, value) // not supported
|
|
1085
|
-
case 'Void':
|
|
1086
|
-
return TypeGuard.TVoid(schema) && Value.Check(schema, value)
|
|
1087
|
-
default:
|
|
1088
|
-
return false
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
|
-
export function createAjv() {
|
|
1093
|
-
return addFormats(new Ajv({}), [
|
|
1094
|
-
'date-time',
|
|
1095
|
-
'time',
|
|
1096
|
-
'date',
|
|
1097
|
-
'email',
|
|
1098
|
-
'hostname',
|
|
1099
|
-
'ipv4',
|
|
1100
|
-
'ipv6',
|
|
1101
|
-
'uri',
|
|
1102
|
-
'uri-reference',
|
|
1103
|
-
'uuid',
|
|
1104
|
-
'uri-template',
|
|
1105
|
-
'json-pointer',
|
|
1106
|
-
'relative-json-pointer',
|
|
1107
|
-
'regex'
|
|
1108
|
-
])
|
|
1109
|
-
.addKeyword({ type: 'object', keyword: 'instanceOf', validate: schemaOf })
|
|
1110
|
-
.addKeyword({ type: 'null', keyword: 'typeOf', validate: schemaOf })
|
|
1111
|
-
.addKeyword('exclusiveMinimumTimestamp')
|
|
1112
|
-
.addKeyword('exclusiveMaximumTimestamp')
|
|
1113
|
-
.addKeyword('minimumTimestamp')
|
|
1114
|
-
.addKeyword('maximumTimestamp')
|
|
1115
|
-
.addKeyword('minByteLength')
|
|
1116
|
-
.addKeyword('maxByteLength')
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
const ajv = createAjv()
|
|
1120
|
-
|
|
1121
|
-
const R = ajv.validate(Type.Object({ // const R = true
|
|
1122
|
-
buffer: Type.Uint8Array(),
|
|
1123
|
-
date: Type.Date(),
|
|
1124
|
-
void: Type.Void()
|
|
1125
|
-
}), {
|
|
1126
|
-
buffer: new Uint8Array(),
|
|
1127
|
-
date: new Date(),
|
|
1128
|
-
void: null
|
|
1129
|
-
})
|
|
1130
|
-
```
|
|
1131
|
-
|
|
1132
|
-
</details>
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
1046
|
<a name='typesystem'></a>
|
|
1136
1047
|
|
|
1137
1048
|
## TypeSystem
|
|
1138
1049
|
|
|
1139
|
-
TypeBox provides an extensible TypeSystem module that enables developers to
|
|
1050
|
+
TypeBox provides an extensible TypeSystem module that enables developers to define additional types above and beyond the built in type set. This module also allows developers to define custom string formats as well as override certain type checking behaviours.
|
|
1140
1051
|
|
|
1141
1052
|
The TypeSystem module is provided as an optional import.
|
|
1142
1053
|
|
|
@@ -1148,7 +1059,7 @@ import { TypeSystem } from '@sinclair/typebox/system'
|
|
|
1148
1059
|
|
|
1149
1060
|
### Types
|
|
1150
1061
|
|
|
1151
|
-
Use the `CreateType(...)` function to specify
|
|
1062
|
+
Use the `CreateType(...)` function to specify custom type. This function will return a type factory function that can be used to construct the type. The following creates and registers a BigNumber type which will statically infer as `bigint`.
|
|
1152
1063
|
|
|
1153
1064
|
```typescript
|
|
1154
1065
|
//--------------------------------------------------------------------------------------------
|
|
@@ -1233,29 +1144,29 @@ This benchmark measures compilation performance for varying types. You can revie
|
|
|
1233
1144
|
┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
|
|
1234
1145
|
│ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
|
|
1235
1146
|
├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
|
|
1236
|
-
│ Number │ 2000 │ '
|
|
1237
|
-
│ String │ 2000 │ '
|
|
1238
|
-
│ Boolean │ 2000 │ '
|
|
1239
|
-
│ Null │ 2000 │ '
|
|
1240
|
-
│ RegEx │ 2000 │ '
|
|
1241
|
-
│ ObjectA │ 2000 │ '
|
|
1242
|
-
│ ObjectB │ 2000 │ '
|
|
1243
|
-
│ Tuple │ 2000 │ '
|
|
1244
|
-
│ Union │ 2000 │ '
|
|
1245
|
-
│ Vector4 │ 2000 │ '
|
|
1246
|
-
│ Matrix4 │ 2000 │ '
|
|
1247
|
-
│ Literal_String │ 2000 │ '
|
|
1248
|
-
│ Literal_Number │ 2000 │ '
|
|
1249
|
-
│ Literal_Boolean │ 2000 │ '
|
|
1250
|
-
│ Array_Number │ 2000 │ '
|
|
1251
|
-
│ Array_String │ 2000 │ '
|
|
1252
|
-
│ Array_Boolean │ 2000 │ '
|
|
1253
|
-
│ Array_ObjectA │ 2000 │ '
|
|
1254
|
-
│ Array_ObjectB │ 2000 │ '
|
|
1255
|
-
│ Array_Tuple │ 2000 │ '
|
|
1256
|
-
│ Array_Union │ 2000 │ '
|
|
1257
|
-
│ Array_Vector4 │ 2000 │ '
|
|
1258
|
-
│ Array_Matrix4 │ 2000 │ '
|
|
1147
|
+
│ Number │ 2000 │ ' 451 ms' │ ' 16 ms' │ ' 28.19 x' │
|
|
1148
|
+
│ String │ 2000 │ ' 338 ms' │ ' 14 ms' │ ' 24.14 x' │
|
|
1149
|
+
│ Boolean │ 2000 │ ' 297 ms' │ ' 13 ms' │ ' 22.85 x' │
|
|
1150
|
+
│ Null │ 2000 │ ' 265 ms' │ ' 8 ms' │ ' 33.13 x' │
|
|
1151
|
+
│ RegEx │ 2000 │ ' 492 ms' │ ' 18 ms' │ ' 27.33 x' │
|
|
1152
|
+
│ ObjectA │ 2000 │ ' 2744 ms' │ ' 55 ms' │ ' 49.89 x' │
|
|
1153
|
+
│ ObjectB │ 2000 │ ' 3005 ms' │ ' 44 ms' │ ' 68.30 x' │
|
|
1154
|
+
│ Tuple │ 2000 │ ' 1283 ms' │ ' 26 ms' │ ' 49.35 x' │
|
|
1155
|
+
│ Union │ 2000 │ ' 1263 ms' │ ' 27 ms' │ ' 46.78 x' │
|
|
1156
|
+
│ Vector4 │ 2000 │ ' 1622 ms' │ ' 23 ms' │ ' 70.52 x' │
|
|
1157
|
+
│ Matrix4 │ 2000 │ ' 888 ms' │ ' 12 ms' │ ' 74.00 x' │
|
|
1158
|
+
│ Literal_String │ 2000 │ ' 344 ms' │ ' 14 ms' │ ' 24.57 x' │
|
|
1159
|
+
│ Literal_Number │ 2000 │ ' 389 ms' │ ' 8 ms' │ ' 48.63 x' │
|
|
1160
|
+
│ Literal_Boolean │ 2000 │ ' 374 ms' │ ' 9 ms' │ ' 41.56 x' │
|
|
1161
|
+
│ Array_Number │ 2000 │ ' 710 ms' │ ' 12 ms' │ ' 59.17 x' │
|
|
1162
|
+
│ Array_String │ 2000 │ ' 739 ms' │ ' 9 ms' │ ' 82.11 x' │
|
|
1163
|
+
│ Array_Boolean │ 2000 │ ' 732 ms' │ ' 7 ms' │ ' 104.57 x' │
|
|
1164
|
+
│ Array_ObjectA │ 2000 │ ' 3733 ms' │ ' 42 ms' │ ' 88.88 x' │
|
|
1165
|
+
│ Array_ObjectB │ 2000 │ ' 3602 ms' │ ' 42 ms' │ ' 85.76 x' │
|
|
1166
|
+
│ Array_Tuple │ 2000 │ ' 2204 ms' │ ' 20 ms' │ ' 110.20 x' │
|
|
1167
|
+
│ Array_Union │ 2000 │ ' 1533 ms' │ ' 24 ms' │ ' 63.88 x' │
|
|
1168
|
+
│ Array_Vector4 │ 2000 │ ' 2263 ms' │ ' 21 ms' │ ' 107.76 x' │
|
|
1169
|
+
│ Array_Matrix4 │ 2000 │ ' 1576 ms' │ ' 14 ms' │ ' 112.57 x' │
|
|
1259
1170
|
└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
|
|
1260
1171
|
```
|
|
1261
1172
|
|
|
@@ -1269,31 +1180,31 @@ This benchmark measures validation performance for varying types. You can review
|
|
|
1269
1180
|
┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
|
|
1270
1181
|
│ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
|
|
1271
1182
|
├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
|
|
1272
|
-
│ Number │ 1000000 │ '
|
|
1273
|
-
│ String │ 1000000 │ '
|
|
1274
|
-
│ Boolean │ 1000000 │ '
|
|
1275
|
-
│ Null │ 1000000 │ '
|
|
1276
|
-
│ RegEx │ 1000000 │ '
|
|
1277
|
-
│ ObjectA │ 1000000 │ '
|
|
1278
|
-
│ ObjectB │ 1000000 │ '
|
|
1279
|
-
│ Tuple │ 1000000 │ '
|
|
1280
|
-
│ Union │ 1000000 │ '
|
|
1281
|
-
│ Recursive │ 1000000 │ '
|
|
1282
|
-
│ Vector4 │ 1000000 │ '
|
|
1283
|
-
│ Matrix4 │ 1000000 │ '
|
|
1284
|
-
│ Literal_String │ 1000000 │ '
|
|
1285
|
-
│ Literal_Number │ 1000000 │ ' 47 ms' │ '
|
|
1286
|
-
│ Literal_Boolean │ 1000000 │ '
|
|
1287
|
-
│ Array_Number │ 1000000 │ '
|
|
1288
|
-
│ Array_String │ 1000000 │ '
|
|
1289
|
-
│ Array_Boolean │ 1000000 │ '
|
|
1290
|
-
│ Array_ObjectA │ 1000000 │ '
|
|
1291
|
-
│ Array_ObjectB │ 1000000 │ '
|
|
1292
|
-
│ Array_Tuple │ 1000000 │ '
|
|
1293
|
-
│ Array_Union │ 1000000 │ '
|
|
1294
|
-
│ Array_Recursive │ 1000000 │ '
|
|
1295
|
-
│ Array_Vector4 │ 1000000 │ '
|
|
1296
|
-
│ Array_Matrix4 │ 1000000 │ '
|
|
1183
|
+
│ Number │ 1000000 │ ' 30 ms' │ ' 7 ms' │ ' 6 ms' │ ' 1.17 x' │
|
|
1184
|
+
│ String │ 1000000 │ ' 23 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
|
|
1185
|
+
│ Boolean │ 1000000 │ ' 22 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
|
|
1186
|
+
│ Null │ 1000000 │ ' 27 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
|
|
1187
|
+
│ RegEx │ 1000000 │ ' 163 ms' │ ' 47 ms' │ ' 38 ms' │ ' 1.24 x' │
|
|
1188
|
+
│ ObjectA │ 1000000 │ ' 654 ms' │ ' 41 ms' │ ' 24 ms' │ ' 1.71 x' │
|
|
1189
|
+
│ ObjectB │ 1000000 │ ' 1173 ms' │ ' 59 ms' │ ' 41 ms' │ ' 1.44 x' │
|
|
1190
|
+
│ Tuple │ 1000000 │ ' 124 ms' │ ' 24 ms' │ ' 17 ms' │ ' 1.41 x' │
|
|
1191
|
+
│ Union │ 1000000 │ ' 332 ms' │ ' 26 ms' │ ' 16 ms' │ ' 1.63 x' │
|
|
1192
|
+
│ Recursive │ 1000000 │ ' 3129 ms' │ ' 412 ms' │ ' 102 ms' │ ' 4.04 x' │
|
|
1193
|
+
│ Vector4 │ 1000000 │ ' 147 ms' │ ' 26 ms' │ ' 13 ms' │ ' 2.00 x' │
|
|
1194
|
+
│ Matrix4 │ 1000000 │ ' 576 ms' │ ' 41 ms' │ ' 28 ms' │ ' 1.46 x' │
|
|
1195
|
+
│ Literal_String │ 1000000 │ ' 51 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
|
|
1196
|
+
│ Literal_Number │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
|
|
1197
|
+
│ Literal_Boolean │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
|
|
1198
|
+
│ Array_Number │ 1000000 │ ' 490 ms' │ ' 33 ms' │ ' 18 ms' │ ' 1.83 x' │
|
|
1199
|
+
│ Array_String │ 1000000 │ ' 502 ms' │ ' 31 ms' │ ' 25 ms' │ ' 1.24 x' │
|
|
1200
|
+
│ Array_Boolean │ 1000000 │ ' 465 ms' │ ' 33 ms' │ ' 27 ms' │ ' 1.22 x' │
|
|
1201
|
+
│ Array_ObjectA │ 1000000 │ ' 15463 ms' │ ' 2470 ms' │ ' 2052 ms' │ ' 1.20 x' │
|
|
1202
|
+
│ Array_ObjectB │ 1000000 │ ' 18047 ms' │ ' 2497 ms' │ ' 2348 ms' │ ' 1.06 x' │
|
|
1203
|
+
│ Array_Tuple │ 1000000 │ ' 1958 ms' │ ' 99 ms' │ ' 77 ms' │ ' 1.29 x' │
|
|
1204
|
+
│ Array_Union │ 1000000 │ ' 5348 ms' │ ' 254 ms' │ ' 89 ms' │ ' 2.85 x' │
|
|
1205
|
+
│ Array_Recursive │ 1000000 │ ' 54643 ms' │ ' 8870 ms' │ ' 1158 ms' │ ' 7.66 x' │
|
|
1206
|
+
│ Array_Vector4 │ 1000000 │ ' 2724 ms' │ ' 105 ms' │ ' 48 ms' │ ' 2.19 x' │
|
|
1207
|
+
│ Array_Matrix4 │ 1000000 │ ' 13821 ms' │ ' 437 ms' │ ' 266 ms' │ ' 1.64 x' │
|
|
1297
1208
|
└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
|
|
1298
1209
|
```
|
|
1299
1210
|
|
|
@@ -1307,14 +1218,15 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
|
|
1307
1218
|
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
|
1308
1219
|
│ (index) │ Compiled │ Minified │ Compression │
|
|
1309
1220
|
├──────────────────────┼────────────┼────────────┼─────────────┤
|
|
1310
|
-
│ typebox/compiler │ '
|
|
1311
|
-
│ typebox/conditional │ '
|
|
1312
|
-
│ typebox/custom │ '
|
|
1313
|
-
│ typebox/format │ '
|
|
1314
|
-
│ typebox/guard │ '
|
|
1315
|
-
│ typebox/hash │ '
|
|
1316
|
-
│ typebox/
|
|
1317
|
-
│ typebox
|
|
1221
|
+
│ typebox/compiler │ ' 65.4 kb' │ ' 32.2 kb' │ '2.03 x' │
|
|
1222
|
+
│ typebox/conditional │ ' 45.5 kb' │ ' 18.6 kb' │ '2.45 x' │
|
|
1223
|
+
│ typebox/custom │ ' 0.6 kb' │ ' 0.2 kb' │ '2.61 x' │
|
|
1224
|
+
│ typebox/format │ ' 0.6 kb' │ ' 0.2 kb' │ '2.66 x' │
|
|
1225
|
+
│ typebox/guard │ ' 23.8 kb' │ ' 11.4 kb' │ '2.08 x' │
|
|
1226
|
+
│ typebox/hash │ ' 4.2 kb' │ ' 1.8 kb' │ '2.30 x' │
|
|
1227
|
+
│ typebox/system │ ' 14.0 kb' │ ' 7.1 kb' │ '1.96 x' │
|
|
1228
|
+
│ typebox/value │ ' 90.0 kb' │ ' 41.8 kb' │ '2.15 x' │
|
|
1229
|
+
│ typebox │ ' 12.0 kb' │ ' 6.4 kb' │ '1.89 x' │
|
|
1318
1230
|
└──────────────────────┴────────────┴────────────┴─────────────┘
|
|
1319
1231
|
```
|
|
1320
1232
|
|
package/typebox.d.ts
CHANGED
|
@@ -172,17 +172,12 @@ export type OptionalPropertyKeys<T extends TProperties> = {
|
|
|
172
172
|
[K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
|
|
173
173
|
}[keyof T];
|
|
174
174
|
export type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
|
|
175
|
-
export type
|
|
176
|
-
|
|
177
|
-
} & {
|
|
178
|
-
readonly [K in ReadonlyPropertyKeys<T>]: Static<T[K], P>;
|
|
179
|
-
} & {
|
|
180
|
-
[K in OptionalPropertyKeys<T>]?: Static<T[K], P>;
|
|
181
|
-
} & {
|
|
182
|
-
[K in RequiredPropertyKeys<T>]: Static<T[K], P>;
|
|
183
|
-
} extends infer R ? {
|
|
184
|
-
[K in keyof R]: R[K];
|
|
175
|
+
export type PropertiesReducer<T extends TProperties, R extends Record<keyof any, unknown>> = (Readonly<Partial<Pick<R, ReadonlyOptionalPropertyKeys<T>>>> & Readonly<Pick<R, ReadonlyPropertyKeys<T>>> & Partial<Pick<R, OptionalPropertyKeys<T>>> & Required<Pick<R, RequiredPropertyKeys<T>>>) extends infer O ? {
|
|
176
|
+
[K in keyof O]: O[K];
|
|
185
177
|
} : never;
|
|
178
|
+
export type PropertiesReduce<T extends TProperties, P extends unknown[]> = PropertiesReducer<T, {
|
|
179
|
+
[K in keyof T]: Static<T[K], P>;
|
|
180
|
+
}>;
|
|
186
181
|
export type TRecordProperties<K extends TUnion<TLiteral[]>, T extends TSchema> = Static<K> extends string ? {
|
|
187
182
|
[X in Static<K>]: T;
|
|
188
183
|
} : never;
|
package/value/cast.js
CHANGED
|
@@ -308,9 +308,6 @@ var ValueCast;
|
|
|
308
308
|
}
|
|
309
309
|
return result;
|
|
310
310
|
}
|
|
311
|
-
function Recursive(schema, references, value) {
|
|
312
|
-
throw new ValueCastRecursiveTypeError(schema);
|
|
313
|
-
}
|
|
314
311
|
function Ref(schema, references, value) {
|
|
315
312
|
const reference = references.find((reference) => reference.$id === schema.$ref);
|
|
316
313
|
if (reference === undefined)
|
|
@@ -386,8 +383,6 @@ var ValueCast;
|
|
|
386
383
|
return Promise(anySchema, anyReferences, value);
|
|
387
384
|
case 'Record':
|
|
388
385
|
return Record(anySchema, anyReferences, value);
|
|
389
|
-
case 'Rec':
|
|
390
|
-
return Recursive(anySchema, anyReferences, value);
|
|
391
386
|
case 'Ref':
|
|
392
387
|
return Ref(anySchema, anyReferences, value);
|
|
393
388
|
case 'Self':
|
package/value/check.js
CHANGED
|
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
|
|
31
31
|
const Types = require("../typebox");
|
|
32
32
|
const index_1 = require("../system/index");
|
|
33
|
+
const extends_1 = require("../guard/extends");
|
|
33
34
|
const index_2 = require("../format/index");
|
|
34
35
|
const index_3 = require("../custom/index");
|
|
35
36
|
const index_4 = require("../hash/index");
|
|
@@ -42,9 +43,15 @@ class ValueCheckUnknownTypeError extends Error {
|
|
|
42
43
|
exports.ValueCheckUnknownTypeError = ValueCheckUnknownTypeError;
|
|
43
44
|
var ValueCheck;
|
|
44
45
|
(function (ValueCheck) {
|
|
46
|
+
// --------------------------------------------------------
|
|
47
|
+
// Guards
|
|
48
|
+
// --------------------------------------------------------
|
|
45
49
|
function IsNumber(value) {
|
|
46
50
|
return typeof value === 'number' && !isNaN(value);
|
|
47
51
|
}
|
|
52
|
+
// --------------------------------------------------------
|
|
53
|
+
// Guards
|
|
54
|
+
// --------------------------------------------------------
|
|
48
55
|
function Any(schema, references, value) {
|
|
49
56
|
return true;
|
|
50
57
|
}
|
|
@@ -207,6 +214,9 @@ var ValueCheck;
|
|
|
207
214
|
if (!Visit(propertySchema, references, value[propertyKey])) {
|
|
208
215
|
return false;
|
|
209
216
|
}
|
|
217
|
+
if (extends_1.TypeExtends.Undefined(propertySchema)) {
|
|
218
|
+
return propertyKey in value;
|
|
219
|
+
}
|
|
210
220
|
}
|
|
211
221
|
else {
|
|
212
222
|
if (value[propertyKey] !== undefined) {
|
package/value/create.js
CHANGED
|
@@ -195,14 +195,6 @@ var ValueCreate;
|
|
|
195
195
|
return {};
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
|
-
function Recursive(schema, references) {
|
|
199
|
-
if (schema.default !== undefined) {
|
|
200
|
-
return schema.default;
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
throw new Error('ValueCreate.Recursive: Recursive types require a default value');
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
198
|
function Ref(schema, references) {
|
|
207
199
|
if (schema.default !== undefined) {
|
|
208
200
|
return schema.default;
|
|
@@ -354,8 +346,6 @@ var ValueCreate;
|
|
|
354
346
|
return Promise(anySchema, anyReferences);
|
|
355
347
|
case 'Record':
|
|
356
348
|
return Record(anySchema, anyReferences);
|
|
357
|
-
case 'Rec':
|
|
358
|
-
return Recursive(anySchema, anyReferences);
|
|
359
349
|
case 'Ref':
|
|
360
350
|
return Ref(anySchema, anyReferences);
|
|
361
351
|
case 'Self':
|